-
+
@@ -64,7 +63,7 @@
Upgrade auf: |
upgradeTo as $link): ?>
- $link->contract_id])?>" class="contract-link =($link->contract->cancel_date && $link->contract->cancel_date <= date('U')) ? "canceled" : ""?>">=$link->contract->product_name?> [=$link->contract->matchcode?>] (=$link->contract_id?>)
+ $link->contract_id])?>" class="contract-link =($link->contract->cancel_date && $link->contract->cancel_date <= date('U')) ? "canceled" : ""?> =(!$link->contract->isFinished()) ? "not-finished" : "" ?>">=$link->contract->product_name?> [=$link->contract->matchcode?>] (=$link->contract_id?>)
|
@@ -233,7 +232,7 @@
$contract->id])?>">
$contract->id])?>">
-
$contract->id])?>" onclick="if(!confirm('Jetzt fertigstellen und in Verrechnung geben?')) return false">
+
$contract->id])?>" onclick="if(!confirm('Jetzt fertigstellen und in Verrechnung geben?')) return false">
@@ -290,11 +289,13 @@
|
value == "manual"): ?>
- Vertrag manuell angelegt
+ Vertrag manuell erstellt
value == "import"): ?>
Vertrag importiert: =nl2br(htmlentities($j->text))?>
value == "order"): ?>
Vertrag aus Bestellung $contract->orderproduct->order_id])?>">#=$contract->orderproduct->order_id?> erstellt
+ value == "productchange"): ?>
+ Vertrag erstellt: =nl2br(htmlentities($j->text))?>
|
type == "contract_finished"): ?>
@@ -311,7 +312,9 @@
value); ?>
|
Verknüpfung mit $link->id])?>">=$link->id?> - =$link->product_name?> [=$link->matchcode?>] erstellt |
-
+ type == "canceled"): ?>
+
|
+
Vertag gekündigt |
$j->id])?>" title="Journaleintrag bearbeiten">
diff --git a/application/ADBHausnummer/ADBHausnummerModel.php b/application/ADBHausnummer/ADBHausnummerModel.php
index 5503bd9e3..6a6d3171e 100644
--- a/application/ADBHausnummer/ADBHausnummerModel.php
+++ b/application/ADBHausnummer/ADBHausnummerModel.php
@@ -256,6 +256,8 @@ class ADBHausnummerModel {
$where .= " AND Hausnummer.netzgebiet_id IN (". implode(",", $netzgebiet_id).")";
} elseif($netzgebiet_id === null) {
$where .= " AND Hausnummer.netzgebiet_id IS NULL";
+ } elseif($netzgebiet_id === true) {
+ $where .= " AND Hausnummer.netzgebiet_id > 0";
}
}
diff --git a/application/Contract/Contract.php b/application/Contract/Contract.php
index a0623e25f..7a8fc4864 100644
--- a/application/Contract/Contract.php
+++ b/application/Contract/Contract.php
@@ -1,572 +1,658 @@
in_after_save) return true;
+ $this->in_after_save++;
+
if($this->billingaddress_id) {
$this->getProperty("billingaddress")->generateFibuAccountNumber();
}
+
+ $this->runTriggers();
+
+ $this->in_after_save--;
}
+ public function runTriggers() {
+ $dir = opendir(__DIR__."/trigger");
+ while($filename = readdir($dir)) {
+ if(strpos($filename, ".") === 0 ) continue;
+ $m = [];
+ if(!preg_match('/^([a-z0-9_]+)\.php$/i', $filename, $m)) continue;
+ $trigger_name = $m[1];
+ $classname = "ContractTrigger_$trigger_name";
+ $filepath = __DIR__."/trigger/$trigger_name.php";
- private function getLinks() {
- $this->linkFrom = [];
- $this->linkTo = [];
- $this->upgradeFrom = [];
- $this->upgradeTo = [];
- $this->downgradeFrom = [];
- $this->downgradeTo = [];
- $this->productchangeFrom = [];
- $this->productchangeTo = [];
- $this->relocationFrom = [];
- $this->relocationTo = [];
-
- // Links targeting this contract (to)
- foreach(ContractLinkModel::search(['origin_contract_id' => $this->id]) as $link) {
- switch($link->type) {
- case "link":
- $this->linkTo[] = $link;
- break;
- case "credit":
- $this->linkTo[] = $link;
- break;
- case "upgrade":
- $this->upgradeTo[] = $link;
- break;
- case "downgrade":
- $this->downgradeTo[] = $link;
- break;
- case "productchange":
- $this->productchangeTo[] = $link;
- break;
- case "relocation":
- $this->relocationTo[] = $link;
- break;
- default:
- $this->log->warn("ContractLink with invalid type: ".$link->id." ".$link->type);
- break;
- }
- }
-
- foreach(ContractLinkModel::search(['contract_id' => $this->id]) as $link) {
- switch($link->type) {
- case "link":
- $this->linkFrom[] = $link;
- break;
- case "credit":
- $this->linkFrom[] = $link;
- break;
- case "upgrade":
- $this->upgradeFrom[] = $link;
- break;
- case "downgrade":
- $this->downgradeFrom[] = $link;
- break;
- case "productchange":
- $this->productchangeFrom[] = $link;
- break;
- case "relocation":
- $this->relocationFrom[] = $link;
- break;
- default:
- $this->log->warn("ContractLink with invalid type: ".$link->id." ".$link->type);
- break;
- }
- }
-
- }
-
-
- public function isCancelled() {
- if(!$this->id) {
- return false;
- }
+ $this->log->debug(__METHOD__.": Looking for $classname in $filepath");
- if(!$this->cancel_date) {
- return false;
- }
-
- $now = date('U');
- if($this->cancel_date <= $now) {
- return true;
- }
-
- return false;
- }
-
- public function isFinished() {
- if(!$this->id) {
- return false;
- }
-
- $now = date('U');
-
- if($this->finish_date && $this->finish_date <= $now) {
- return true;
- }
-
- if($this->cancel_date && $this->cancel_date <= $now) {
- return true;
- }
-
- return false;
- }
-
- public function generateMatchcode() {
- $owner_address = $this->getProperty("owner")->street.", ".$this->getProperty("owner")->zip." ".$this->getProperty("owner")->city;
-
- if($this->termination_id) {
- $termination = new Termination($this->termination_id);
- $termination_address = $termination->building->street.", ".$termination->building->zip." ".$termination->building->city;
- return $termination_address;
- }
-
- $product = $this->getProperty("product");
- /*
- * exceptions for certain products
- */
- foreach(["dsl", "standortgeber", "funkinternet", "glasfaser", "brettljausn"] as $qname) {
- $qname = strtolower($qname);
- $product_name = strtolower($product->name);
- if(stripos($product_name, $qname) !== false) {
- return $owner_address;
- }
- }
-
- return false;
- }
-
-
- public function addFilesFromOrder() {
- if(!$this->orderproduct_id) {
- return true;
- }
-
- $op = $this->getProperty("orderproduct");
- $order = $op->order;
- if(!$order || !$order->id) return true;
-
- foreach($order->files as $file) {
- $cfile = ContractFileModel::create([
- "contract_id" => $this->id,
- "file_id" => $file->file_id,
- "name" => $file->name,
- "description" => $file->description,
- "create_by" => $file->create_by,
- "edit_by" => $file->edit_by
- ]);
- $cfile->save();
-
- $journal = ContractjournalModel::create([
- "contract_id" => $this->id,
- "type" => "file",
- "value" => $cfile->id,
- "text" => (array_key_exists($cfile->name, TT_ORDER_FILE_TYPES)) ? TT_ORDER_FILE_TYPES[$cfile->name] : $cfile->name
- ]);
- $journal->save();
- }
-
-
- }
-
- public function getVoicenumbers() {
- $voicenumber = $this->getConfigValue("voicenumberblock_voicenumber");
- $numbers = json_decode($voicenumber->json);
- return $numbers;
- }
-
- public function getConfigValue($itemname) {
- $configvalues = $this->getProperty("configvalues");
- if(!$configvalues) return null;
- if(!array_key_exists($itemname, $configvalues)) return null;
-
- $configitem = $configvalues[$itemname];
- return $configitem->value;
- }
-
- public function setConfigValue($itemname, $value) {
- $configvalues = $this->getProperty("configvalues");
- if(!$configvalues) return null;
- if(!array_key_exists($itemname, $configvalues)) return null;
-
- $configitem = $configvalues[$itemname];
-
- $configitem->value->set($value);
- $configitem->value->save();
- return true;
- }
-
- public function sendCancelNotification($linked_contracts = []) {
- $pdf_vars = [
- "contract" => $this,
- "linked_contracts" => $linked_contracts,
- "owner" => $this->getProperty("owner")
- ];
- $pdf = new PdfForm("Emailtemplates/attachments/cancel_notification.pdf", $pdf_vars);
- //$pdf->download();
- //exit;
- $pdfpath = $pdf->render();
- $tvalue = $pdf->getReturnedValues();
- $pdfname = $tvalue["filename"];
-
- // send email to customer
- $tpl = new Layout();
- $tpl->setTemplate("Emailtemplates/customer/cancel_notification");
-
- foreach($pdf_vars as $name => $val) {
- $tpl->set($name, $val);
- }
-
- $body = $tpl->render();
- $values = $tpl->getReturnedValue();
-
- $subject = $values['subject'];
- $from = $values['from_email'];
- $from_name = $values['from_email_name'];
- $to = $this->owner->email;
-
- if(!$subject || !$from || !$from_name || !$to) {
- $this->log->warn("Service PIN Email not sent. (subject: '$subject', from: '$from_name', from_email: '$from', to: '$to')");
- } else {
- $email = new Emailnotification();
- $email->setSubject($subject);
- $email->setBody($body);
- $email->setFrom($from, $from_name);
- $email->setTo($to);
- $email->setHeader("X-".MFAPPNAME."-Cid", $this->id);
- $email->addAttachment($pdfpath, null, $pdfname, "application/pdf");
- $email->send();
-
- $oemail = new Emailnotification();
- $oemail->setSubject("Kündigungbestätigung ".$this->owner->customer_number." ".str_replace(["\n", "\r"], "", $this->owner->getCompanyOrName()));
- $oemail->setBody($body);
- $oemail->setFrom($from, $from_name);
- $oemail->setTo("office@xinon.at");
- $oemail->setHeader("X-".MFAPPNAME."-Cid", $this->id);
- $oemail->addAttachment($pdfpath, null, $pdfname, "application/pdf");
-
- $oemail->send();
-
- $this->log->info(__METHOD__.": Sending Cancel Notication for ".$this->owner_id." to $to");
- }
-
- $tk_tpl = new Layout();
- $tk_tpl->setTemplate("Emailtemplates/customer/cancel_ticket");
-
- foreach($pdf_vars as $name => $val) {
- $tk_tpl->set($name, $val);
- }
-
- $tk_body = $tk_tpl->render();
- $tk_values = $tk_tpl->getReturnedValue();
-
- $tk_email = new Emailnotification();
- $tk_email->setSubject($tk_values["subject"]);
- $tk_email->setBody($tk_body);
- $tk_email->setFrom($tk_values["from_email"], $tk_values["from_email_name"]);
- $tk_email->setTo("workspace@xinon.at");
- $tk_email->setHeader("X-".MFAPPNAME."-Cid", $this->id);
- $tk_email->send();
-
- }
-
- public function getProperty($name) {
- if($this->$name == null) {
-
- if($name == "billingaddress" && $this->billingaddress_id) {
- $this->billingaddress = mfValuecache::singleton()->get("mfObjectmodel-Address-".$this->billingaddress_id);
- if($this->billingaddress === null) {
- $this->billingaddress = new Address($this->billingaddress_id);
- if($this->billingaddress->id) {
- mfValuecache::singleton()->set("mfObjectmodel-Address-".$this->billingaddress_id, $this->billingaddress);
- }
- }
- return $this->billingaddress;
- }
-
- if($name == "owner" && $this->owner_id) {
- $this->owner = mfValuecache::singleton()->get("mfObjectmodel-Address-".$this->owner_id);
- if($this->owner === null) {
- $this->owner = new Address($this->owner_id);
- if($this->owner->id) {
- mfValuecache::singleton()->set("mfObjectmodel-Address-".$this->owner_id, $this->owner);
- }
- }
- return $this->owner;
- }
-
- if($name == "product") {
- $this->product = mfValuecache::singleton()->get("mfObjectmodel-Product-".$this->product_id);
- if($this->product === null) {
- $this->product = new Product($this->product_id);
- if($this->product->id) {
- mfValuecache::singleton()->set("mfObjectmodel-Product-".$this->product_id, $this->product);
- }
- }
- return $this->product;
- }
-
- if($name == "orderproduct") {
- $this->orderproduct = mfValuecache::singleton()->get("mfObjectmodel-OrderProduct-".$this->orderproduct_id);
- if($this->orderproduct === null) {
- $this->orderproduct = new OrderProduct($this->orderproduct_id);
- if($this->orderproduct->id) {
- mfValuecache::singleton()->set("mfObjectmodel-OrderProduct-".$this->orderproduct_id, $this->orderproduct);
- }
- }
- return $this->orderproduct;
- }
-
- /*if($name == "contractConfigGroups") {
- $product = $this->getProperty("product");
- $this->contractConfigGroups = ContractconfigGroupModel::search(['producttech_id' => $product->producttech_id]);
- return $this->contractConfigGroups;
- }*/
-
- if($name == "configgroups") {
- $product = $this->getProperty("product");
- $this->configgroups = [];
- foreach(ContractconfiggroupProductgroupModel::search(['productgroup_id' => $product->productgroup_id]) as $ccpg) {
- $ccpg->contractconfiggroup->setContractId($this->id);
- $this->configgroups[] = $ccpg->contractconfiggroup;
+ if(!file_exists($filepath)) {
+ $this->log->debug(__METHOD__.": $filepath not found");
+ continue;
}
- return $this->configgroups;
- }
+ require_once $filepath;
- if($name == "configvalues") {
- $this->configvalues = [];
- foreach($this->getProperty("configgroups") as $group) {
- foreach($group->items as $item) {
- $this->configvalues[$item->name] = $item;
+ if(!class_exists($classname)) {
+ $this->log->debug(__METHOD__.": $classname not found");
+ continue;
+ }
+
+ $me = new User();
+ $me->loadMe();
+
+ $injection = [
+ "db" => $this->db,
+ "log" => $this->log,
+ "me" => $me,
+ "contract" => $this
+ ];
+
+ try {
+ $trigger = new $classname($injection);
+ if($trigger->precheck()) {
+ $this->log->debug(__METHOD__.": precheck successful: running");
+ $trigger->run();
}
+ } catch(Exception $e) {
+ throw $e;
}
- return $this->configvalues;
}
- if(!$this->id) {
- return null;
- }
-
-
-
-
+ }
-
+ public function getRegularCanceldate($format = "d.m.Y") {
+ if(!$this->finish_date) return "";
-
+ $today = new DateTime();
+ $tomorrow = clone($today);
+ $tomorrow->modify("+1 day");
+
+ $finish_date = new DateTime("@".$this->finish_date);
+ $finish_date->setTimezone(new DateTimeZone("Europe/Vienna"));
+
+ $period_end_date = clone($finish_date);
+ $period_end_date->modify("+".$this->contract_term." months");
+
+ while($period_end_date->format("Y-m-d") <= $today->format("Y-m-d")) {
+ $period_end_date = $period_end_date->modify("+".$this->billing_period." months");
+
+ }
+ $period_end_date->modify("-1 day");
+ return $period_end_date->format($format);
+ }
+
+ public function getNextBillingPeriodEnd($format = "d.m.Y") {
+ if(!$this->finish_date) return "";
+
+ $today = new DateTime();
+
+ $finish_date = new DateTime("@".$this->finish_date);
+ $finish_date->setTimezone(new DateTimeZone("Europe/Vienna"));
+
+ $next_billing_period = clone($finish_date);
+ $next_billing_period->modify("+".$this->billing_period." months");
+ while($next_billing_period->format("Y-m-d") <= $today->format("Y-m-d")) {
+ $next_billing_period->modify("+".$this->billing_period." months");
+ }
+ $next_billing_period->modify("-1 day");
+
+ return $next_billing_period->format($format);
+ }
+
+ private function getLinks() {
+ $this->linkFrom = [];
+ $this->linkTo = [];
+ $this->upgradeFrom = [];
+ $this->upgradeTo = [];
+ $this->downgradeFrom = [];
+ $this->downgradeTo = [];
+ $this->productchangeFrom = [];
+ $this->productchangeTo = [];
+ $this->relocationFrom = [];
+ $this->relocationTo = [];
+
+ // Links targeting this contract (to)
+ foreach(ContractLinkModel::search(['origin_contract_id' => $this->id]) as $link) {
+ switch($link->type) {
+ case "link":
+ $this->linkTo[] = $link;
+ break;
+ case "credit":
+ $this->linkTo[] = $link;
+ break;
+ case "upgrade":
+ $this->upgradeTo[] = $link;
+ break;
+ case "downgrade":
+ $this->downgradeTo[] = $link;
+ break;
+ case "productchange":
+ $this->productchangeTo[] = $link;
+ break;
+ case "relocation":
+ $this->relocationTo[] = $link;
+ break;
+ default:
+ $this->log->warn("ContractLink with invalid type: " . $link->id . " " . $link->type);
+ break;
+ }
+ }
+
+ foreach(ContractLinkModel::search(['contract_id' => $this->id]) as $link) {
+ switch($link->type) {
+ case "link":
+ $this->linkFrom[] = $link;
+ break;
+ case "credit":
+ $this->linkFrom[] = $link;
+ break;
+ case "upgrade":
+ $this->upgradeFrom[] = $link;
+ break;
+ case "downgrade":
+ $this->downgradeFrom[] = $link;
+ break;
+ case "productchange":
+ $this->productchangeFrom[] = $link;
+ break;
+ case "relocation":
+ $this->relocationFrom[] = $link;
+ break;
+ default:
+ $this->log->warn("ContractLink with invalid type: " . $link->id . " " . $link->type);
+ break;
+ }
+ }
+
+ }
+
+
+ public function isCancelled() {
+ if(!$this->id) {
+ return false;
+ }
+
+ if(!$this->cancel_date) {
+ return false;
+ }
+
+ $now = date('U');
+ if($this->cancel_date <= $now) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public function isFinished() {
+ if(!$this->id) {
+ return false;
+ }
+
+ $now = date('U');
+
+ if($this->finish_date && $this->finish_date <= $now) {
+ return true;
+ }
+
+ if($this->cancel_date && $this->cancel_date <= $now) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public function generateMatchcode() {
+ $owner_address = $this->getProperty("owner")->street . ", " . $this->getProperty("owner")->zip . " " . $this->getProperty("owner")->city;
+
+ if($this->termination_id) {
+ $termination = new Termination($this->termination_id);
+ $termination_address = $termination->building->street . ", " . $termination->building->zip . " " . $termination->building->city;
+ return $termination_address;
+ }
-
- /*if($name == "contractConfigItems") {
$product = $this->getProperty("product");
-
- $this->contractConfigItems = [];
- foreach(ProducttechAttributeModel::search(['producttech_id' => $product->producttech_id, "forcontract" => 1]) as $item) {
- $item->setContractId($this->id);
- $this->contractConfigItems [] = $item;
- }
-
- return $this->contractConfigItems;
- }*/
-
- if($name == "vatrate") {
- $vatgroup = $this->getProperty("vatgroup");
- $country = $this->getProperty("country");
- $vatrate = $vatgroup->rates["domestic"]->rate;
- if($this->country_id && $country->is_eu) {
- $vatrate = $vatgroup->rates["eu"]->rate;
- } if($this->country_id && !$country->is_eu) {
- $vatrate = $vatgroup->rates["other"]->rate;
+ /*
+ * exceptions for certain products
+ */
+ foreach(["dsl", "standortgeber", "funkinternet", "glasfaser", "brettljausn"] as $qname) {
+ $qname = strtolower($qname);
+ $product_name = strtolower($product->name);
+ if(stripos($product_name, $qname) !== false) {
+ return $owner_address;
}
- $this->vatrate = $vatrate;
- return $this->vatrate;
}
- if($name == "voicenumbers") {
- $numbers = $this->getVoicenumbers();
- $this->voicenumbers = $numbers;
- return $this->voicenumbers;
- }
-
- if($name == "journals") {
- $this->journals = array_reverse(ContractjournalModel::search(["contract_id" => $this->id]));
- return $this->journals;
- }
-
- if($name == "orderjournals") {
- if(!$this->orderproduct_id) return null;
-
- $journals = [];
-
- $order = $this->getProperty("orderproduct")->order;
- foreach($order->journal as $j) {
- $oj = new Contractjournal();
- $oj->type = "order_comment";
- $oj->value = "";
- $oj->text = $j->text;
- $journals[] = $oj;
- }
-
- $this->orderjournals = $journals;
- return $this->orderjournals;
- }
-
- if($name == "links") {
- $this->links = ContractLinkModel::includesContractId($this->id, ["type" => "link"]);
- //var_dump($this->links);exit;
- return $this->links;
- }
-
- if($name == "linksWithCredit") {
- $this->linksWithCredit = ContractLinkModel::includesContractId($this->id, ["type" => ["link", "credit"]]);
- //var_dump($this->links);exit;
- return $this->linksWithCredit;
- }
-
- if(in_array($name, ['linkFrom','linkTo','upgradeFrom','upgradeTo','downgradeFrom','downgradeTo','productchangeFrom','productchangeTo','relocationFrom','relocationTo'])) {
- if($this->$name === null) {
- $this->getLinks();
- }
- return $this->$name;
- }
-
- if($name == "finisher") {
- $this->finisher = mfValuecache::singleton()->get("Worker-id-".$this->finish_date_by);
- if($this->finisher === null) {
- $this->finisher = new User($this->finish_date_by);
- if($this->finisher->id) {
- mfValuecache::singleton()->set("Worker-id-".$this->finish_date_by, $this->finisher);
- }
- }
- return $this->finisher;
- }
-
- if($name == "canceler") {
- $this->canceler = mfValuecache::singleton()->get("Worker-id-".$this->cancel_date_by);
- if($this->canceler === null) {
- $this->canceler = new User($this->cancel_date_by);
- if($this->canceler->id) {
- mfValuecache::singleton()->set("Worker-id-".$this->cancel_date_by, $this->canceler);
- }
- }
- return $this->canceler;
- }
-
- if($name == "creator") {
- $this->creator = mfValuecache::singleton()->get("Worker-id-".$this->create_by);
- if($this->creator === null) {
- $this->creator = new User($this->create_by);
- if($this->creator->id) {
- mfValuecache::singleton()->set("Worker-id-".$this->create_by, $this->creator);
- }
- }
- return $this->creator;
- }
-
- if($name == "editor") {
- $this->editor = mfValuecache::singleton()->get("Worker-id-".$this->edit_by);
- if($this->editor === null) {
- $this->editor = new User($this->edit_by);
- if($this->editor->id) {
- mfValuecache::singleton()->set("Worker-id-".$this->edit_by, $this->editor);
- }
- }
- return $this->editor;
- }
-
- $classname = ucfirst($name);
- $idfield = $name."_id";
- $this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-".$this->$idfield);
- if(!$this->$name) {
- $this->$name = new $classname($this->$idfield);
- }
-
- if($this->$name->id) {
- mfValuecache::singleton()->set("mfObjectmodel-$name-".$this->$name->id, $this->$name);
- return $this->$name;
- } else {
- return null;
- }
-
+ return false;
}
-
- return $this->$name;
- }
-
-
-
- /*
- * When object is cloned, new object will call this funtion to let us clean up the new Contract.
- * Throws Exception if cloning fails.
- */
- public function __clone() {
- $me = new User;
- $me->loadMe();
-
- $old_id = $this->id;
- $this->id = null;
-
-
- // cleanup Contract daten
- $this->orderproduct_id = null;
- $this->order_date = null;
- $this->finish_date = null;
- $this->finish_date_by = null;
- $this->cancel_date = null;
- $this->cancel_date_by = null;
- $this->create_by = $me->id;
- $this->edit_by = $me->id;
-
- $this->create = null;
- $this->edit = null;
- $this->saved = 0;
- $this->mode = "new";
- $this->_old_data = new StdClass();
-
- //$this->save();
-
- if($old_id == $this->id) {
- $this->log->error("save() of cloned Contract $old_id failed!");
- throw new Exception("Saving clone failed.");
+
+
+ public function addFilesFromOrder() {
+ if(!$this->orderproduct_id) {
+ return true;
+ }
+
+ $op = $this->getProperty("orderproduct");
+ $order = $op->order;
+ if(!$order || !$order->id) return true;
+
+ foreach($order->files as $file) {
+ $cfile = ContractFileModel::create([
+ "contract_id" => $this->id,
+ "file_id" => $file->file_id,
+ "name" => $file->name,
+ "description" => $file->description,
+ "create_by" => $file->create_by,
+ "edit_by" => $file->edit_by
+ ]);
+ $cfile->save();
+
+ $journal = ContractjournalModel::create([
+ "contract_id" => $this->id,
+ "type" => "file",
+ "value" => $cfile->id,
+ "text" => (array_key_exists($cfile->name, TT_ORDER_FILE_TYPES)) ? TT_ORDER_FILE_TYPES[$cfile->name] : $cfile->name
+ ]);
+ $journal->save();
+ }
+
+
+ }
+
+ public function getVoicenumbers() {
+ $voicenumber = $this->getConfigValue("voicenumberblock_voicenumber");
+ $numbers = json_decode($voicenumber->json);
+ return $numbers;
+ }
+
+ public function getConfigValue($itemname) {
+ $configvalues = $this->getProperty("configvalues");
+ if(!$configvalues) return null;
+ if(!array_key_exists($itemname, $configvalues)) return null;
+
+ $configitem = $configvalues[$itemname];
+ return $configitem->value;
+ }
+
+ public function setConfigValue($itemname, $value) {
+ $configvalues = $this->getProperty("configvalues");
+ if(!$configvalues) return null;
+ if(!array_key_exists($itemname, $configvalues)) return null;
+
+ $configitem = $configvalues[$itemname];
+
+ $configitem->value->set($value);
+ $configitem->value->save();
+ return true;
+ }
+
+ public function sendCancelNotification($linked_contracts = []) {
+ $pdf_vars = [
+ "contract" => $this,
+ "linked_contracts" => $linked_contracts,
+ "owner" => $this->getProperty("owner")
+ ];
+ $pdf = new PdfForm("Emailtemplates/attachments/cancel_notification.pdf", $pdf_vars);
+ //$pdf->download();
+ //exit;
+ $pdfpath = $pdf->render();
+ $tvalue = $pdf->getReturnedValues();
+ $pdfname = $tvalue["filename"];
+
+ // send email to customer
+ $tpl = new Layout();
+ $tpl->setTemplate("Emailtemplates/customer/cancel_notification");
+
+ foreach($pdf_vars as $name => $val) {
+ $tpl->set($name, $val);
+ }
+
+ $body = $tpl->render();
+ $values = $tpl->getReturnedValue();
+
+ $subject = $values['subject'];
+ $from = $values['from_email'];
+ $from_name = $values['from_email_name'];
+ $to = $this->owner->email;
+
+ if(!$subject || !$from || !$from_name || !$to) {
+ $this->log->warn("Service PIN Email not sent. (subject: '$subject', from: '$from_name', from_email: '$from', to: '$to')");
+ } else {
+ $email = new Emailnotification();
+ $email->setSubject($subject);
+ $email->setBody($body);
+ $email->setFrom($from, $from_name);
+ $email->setTo($to);
+ $email->setHeader("X-" . MFAPPNAME . "-Cid", $this->id);
+ $email->addAttachment($pdfpath, null, $pdfname, "application/pdf");
+ $email->send();
+
+ $oemail = new Emailnotification();
+ $oemail->setSubject("Kündigungbestätigung " . $this->owner->customer_number . " " . str_replace(["\n", "\r"], "", $this->owner->getCompanyOrName()));
+ $oemail->setBody($body);
+ $oemail->setFrom($from, $from_name);
+ $oemail->setTo("office@xinon.at");
+ $oemail->setHeader("X-" . MFAPPNAME . "-Cid", $this->id);
+ $oemail->addAttachment($pdfpath, null, $pdfname, "application/pdf");
+
+ $oemail->send();
+
+ $this->log->info(__METHOD__ . ": Sending Cancel Notication for " . $this->owner_id . " to $to");
+ }
+
+ $tk_tpl = new Layout();
+ $tk_tpl->setTemplate("Emailtemplates/customer/cancel_ticket");
+
+ foreach($pdf_vars as $name => $val) {
+ $tk_tpl->set($name, $val);
+ }
+
+ $tk_body = $tk_tpl->render();
+ $tk_values = $tk_tpl->getReturnedValue();
+
+ $tk_email = new Emailnotification();
+ $tk_email->setSubject($tk_values["subject"]);
+ $tk_email->setBody($tk_body);
+ $tk_email->setFrom($tk_values["from_email"], $tk_values["from_email_name"]);
+ $tk_email->setTo("workspace@xinon.at");
+ $tk_email->setHeader("X-" . MFAPPNAME . "-Cid", $this->id);
+ $tk_email->send();
+
+ }
+
+ public function getProperty($name) {
+ if($this->$name == null) {
+
+ if($name == "billingaddress" && $this->billingaddress_id) {
+ $this->billingaddress = mfValuecache::singleton()->get("mfObjectmodel-Address-" . $this->billingaddress_id);
+ if($this->billingaddress === null) {
+ $this->billingaddress = new Address($this->billingaddress_id);
+ if($this->billingaddress->id) {
+ mfValuecache::singleton()->set("mfObjectmodel-Address-" . $this->billingaddress_id, $this->billingaddress);
+ }
+ }
+ return $this->billingaddress;
+ }
+
+ if($name == "owner" && $this->owner_id) {
+ $this->owner = mfValuecache::singleton()->get("mfObjectmodel-Address-" . $this->owner_id);
+ if($this->owner === null) {
+ $this->owner = new Address($this->owner_id);
+ if($this->owner->id) {
+ mfValuecache::singleton()->set("mfObjectmodel-Address-" . $this->owner_id, $this->owner);
+ }
+ }
+ return $this->owner;
+ }
+
+ if($name == "product") {
+ $this->product = mfValuecache::singleton()->get("mfObjectmodel-Product-" . $this->product_id);
+ if($this->product === null) {
+ $this->product = new Product($this->product_id);
+ if($this->product->id) {
+ mfValuecache::singleton()->set("mfObjectmodel-Product-" . $this->product_id, $this->product);
+ }
+ }
+ return $this->product;
+ }
+
+ if($name == "orderproduct") {
+ $this->orderproduct = mfValuecache::singleton()->get("mfObjectmodel-OrderProduct-" . $this->orderproduct_id);
+ if($this->orderproduct === null) {
+ $this->orderproduct = new OrderProduct($this->orderproduct_id);
+ if($this->orderproduct->id) {
+ mfValuecache::singleton()->set("mfObjectmodel-OrderProduct-" . $this->orderproduct_id, $this->orderproduct);
+ }
+ }
+ return $this->orderproduct;
+ }
+
+ /*if($name == "contractConfigGroups") {
+ $product = $this->getProperty("product");
+ $this->contractConfigGroups = ContractconfigGroupModel::search(['producttech_id' => $product->producttech_id]);
+ return $this->contractConfigGroups;
+ }*/
+
+ if($name == "configgroups") {
+ $product = $this->getProperty("product");
+ $this->configgroups = [];
+ foreach(ContractconfiggroupProductgroupModel::search(['productgroup_id' => $product->productgroup_id]) as $ccpg) {
+ $ccpg->contractconfiggroup->setContractId($this->id);
+ $this->configgroups[] = $ccpg->contractconfiggroup;
+ }
+
+ return $this->configgroups;
+ }
+
+ if($name == "configvalues") {
+ $this->configvalues = [];
+ foreach($this->getProperty("configgroups") as $group) {
+ foreach($group->items as $item) {
+ $this->configvalues[$item->name] = $item;
+ }
+ }
+
+ return $this->configvalues;
+ }
+
+ if(!$this->id) {
+ return null;
+ }
+
+
+ /*if($name == "contractConfigItems") {
+ $product = $this->getProperty("product");
+
+ $this->contractConfigItems = [];
+ foreach(ProducttechAttributeModel::search(['producttech_id' => $product->producttech_id, "forcontract" => 1]) as $item) {
+ $item->setContractId($this->id);
+ $this->contractConfigItems [] = $item;
+ }
+
+ return $this->contractConfigItems;
+ }*/
+
+ if($name == "vatrate") {
+ $vatgroup = $this->getProperty("vatgroup");
+ $country = $this->getProperty("country");
+ $vatrate = $vatgroup->rates["domestic"]->rate;
+ if($this->country_id && $country->is_eu) {
+ $vatrate = $vatgroup->rates["eu"]->rate;
+ }
+ if($this->country_id && !$country->is_eu) {
+ $vatrate = $vatgroup->rates["other"]->rate;
+ }
+ $this->vatrate = $vatrate;
+ return $this->vatrate;
+ }
+
+ if($name == "voicenumbers") {
+ $numbers = $this->getVoicenumbers();
+ $this->voicenumbers = $numbers;
+ return $this->voicenumbers;
+ }
+
+ if($name == "journals") {
+ $this->journals = array_reverse(ContractjournalModel::search(["contract_id" => $this->id]));
+ return $this->journals;
+ }
+
+ if($name == "orderjournals") {
+ if(!$this->orderproduct_id) return null;
+
+ $journals = [];
+
+ $order = $this->getProperty("orderproduct")->order;
+ foreach($order->journal as $j) {
+ $oj = new Contractjournal();
+ $oj->type = "order_comment";
+ $oj->value = "";
+ $oj->text = $j->text;
+ $journals[] = $oj;
+ }
+
+ $this->orderjournals = $journals;
+ return $this->orderjournals;
+ }
+
+ if($name == "links") {
+ $this->links = ContractLinkModel::includesContractId($this->id, ["type" => "link"]);
+ //var_dump($this->links);exit;
+ return $this->links;
+ }
+
+ if($name == "linksWithCredit") {
+ $this->linksWithCredit = ContractLinkModel::includesContractId($this->id, ["type" => ["link", "credit"]]);
+ //var_dump($this->links);exit;
+ return $this->linksWithCredit;
+ }
+
+ if(in_array($name, ['linkFrom', 'linkTo', 'upgradeFrom', 'upgradeTo', 'downgradeFrom', 'downgradeTo', 'productchangeFrom', 'productchangeTo', 'relocationFrom', 'relocationTo'])) {
+ if($this->$name === null) {
+ $this->getLinks();
+ }
+ return $this->$name;
+ }
+
+ if($name == "finisher") {
+ $this->finisher = mfValuecache::singleton()->get("Worker-id-" . $this->finish_date_by);
+ if($this->finisher === null) {
+ $this->finisher = new User($this->finish_date_by);
+ if($this->finisher->id) {
+ mfValuecache::singleton()->set("Worker-id-" . $this->finish_date_by, $this->finisher);
+ }
+ }
+ return $this->finisher;
+ }
+
+ if($name == "canceler") {
+ $this->canceler = mfValuecache::singleton()->get("Worker-id-" . $this->cancel_date_by);
+ if($this->canceler === null) {
+ $this->canceler = new User($this->cancel_date_by);
+ if($this->canceler->id) {
+ mfValuecache::singleton()->set("Worker-id-" . $this->cancel_date_by, $this->canceler);
+ }
+ }
+ return $this->canceler;
+ }
+
+ if($name == "creator") {
+ $this->creator = mfValuecache::singleton()->get("Worker-id-" . $this->create_by);
+ if($this->creator === null) {
+ $this->creator = new User($this->create_by);
+ if($this->creator->id) {
+ mfValuecache::singleton()->set("Worker-id-" . $this->create_by, $this->creator);
+ }
+ }
+ return $this->creator;
+ }
+
+ if($name == "editor") {
+ $this->editor = mfValuecache::singleton()->get("Worker-id-" . $this->edit_by);
+ if($this->editor === null) {
+ $this->editor = new User($this->edit_by);
+ if($this->editor->id) {
+ mfValuecache::singleton()->set("Worker-id-" . $this->edit_by, $this->editor);
+ }
+ }
+ return $this->editor;
+ }
+
+ $classname = ucfirst($name);
+ $idfield = $name . "_id";
+ $this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-" . $this->$idfield);
+ if(!$this->$name) {
+ $this->$name = new $classname($this->$idfield);
+ }
+
+ if($this->$name->id) {
+ mfValuecache::singleton()->set("mfObjectmodel-$name-" . $this->$name->id, $this->$name);
+ return $this->$name;
+ } else {
+ return null;
+ }
+
+ }
+
+ return $this->$name;
+ }
+
+
+ /*
+ * When object is cloned, new object will call this funtion to let us clean up the new Contract.
+ * Throws Exception if cloning fails.
+ */
+ public function __clone() {
+ $me = new User;
+ $me->loadMe();
+
+ $old_id = $this->id;
+ $this->id = null;
+
+
+ // cleanup Contract daten
+ $this->orderproduct_id = null;
+ $this->order_date = null;
+ $this->finish_date = null;
+ $this->finish_date_by = null;
+ $this->cancel_date = null;
+ $this->cancel_date_by = null;
+ $this->create_by = $me->id;
+ $this->edit_by = $me->id;
+
+ $this->create = null;
+ $this->edit = null;
+ $this->saved = 0;
+ $this->mode = "new";
+ $this->_old_data = new StdClass();
+
+ //$this->save();
+
+ if($old_id == $this->id) {
+ $this->log->error("save() of cloned Contract $old_id failed!");
+ throw new Exception("Saving clone failed.");
+ }
+
+ $this->log->debug("Cloned Contract $old_id");
}
-
- $this->log->debug("Cloned Contract $old_id");
- }
}
\ No newline at end of file
diff --git a/application/Contract/ContractController.php b/application/Contract/ContractController.php
index 1f0c05050..ec6cf2ebb 100644
--- a/application/Contract/ContractController.php
+++ b/application/Contract/ContractController.php
@@ -140,34 +140,13 @@ class ContractController extends mfBaseController
$this->redirect("Contract", "view", ["contract_id" => $contract->id]);
}
- if($contract->finish_date) {
- $today = new DateTime();
- $tomorrow = clone($today);
- $tomorrow->modify("+1 day");
+ $today = new DateTime();
+ $tomorrow = clone($today);
+ $tomorrow->modify("+1 day");
- $finish_date = new DateTime("@".$contract->finish_date);
- $finish_date->setTimezone(new DateTimeZone("Europe/Vienna"));
-
- $period_end_date = clone($finish_date);
- $period_end_date->modify("+".$contract->contract_term." months");
-
- while($period_end_date->format("Y-m-d") <= $today->format("Y-m-d")) {
- $period_end_date = $finish_date->modify("+".$contract->billing_period." months");
-
- }
- $period_end_date->modify("-1 day");
-
- $next_billing_period = clone($finish_date);
- $next_billing_period->modify("+".$contract->billing_period." months");
- while($next_billing_period->format("Y-m-d") <= $today->format("Y-m-d")) {
- $next_billing_period->modify("+".$contract->billing_period." months");
- }
- $next_billing_period->modify("-1 day");
-
- $this->layout()->set("tomorrow", $tomorrow);
- $this->layout()->set("term_end_date", $period_end_date);
- $this->layout()->set("period_end_date", $next_billing_period);
- }
+ $this->layout()->set("tomorrow", $tomorrow);
+ $this->layout()->set("term_end_date", $contract->getRegularCanceldate());
+ $this->layout()->set("period_end_date", $contract->getNextBillingPeriodEnd());
$this->layout()->set("contract", $contract);
@@ -191,7 +170,7 @@ class ContractController extends mfBaseController
try {
$cancel_date = DateTime::createFromFormat("d.m.Y", trim($r->cancel_date), new DateTimeZone("Europe/Vienna"));
- $cancel_date->setTime(2,0,0);
+ $cancel_date->setTime(23,59,59);
} catch(Exception $e) {
$this->layout()->setFlash("Ungültiges Datumsformat");
$this->redirect("Contract", "cancel", ["contract_id" => $contract->id]);
@@ -288,6 +267,7 @@ class ContractController extends mfBaseController
protected function saveProductchangeAction()
{
$r = $this->request;
+ //var_dump($r->links);exit;
$id = $r->contract_id;
if (!is_numeric($id) || !$id) {
@@ -330,6 +310,22 @@ class ContractController extends mfBaseController
$contract_data['product_external_id'] = $product->external_id;
$contract_data['sla_id'] = $product->sla_id;
+ if($r->finish_date) {
+ try {
+ $finish_date = DateTime::createFromFormat("d.m.Y", $r->finish_date, new DateTimeZone("Europe/Vienna"));
+ } catch (Exception $e) {
+ $this->layout()->setFlash("Ungültiges Kündigungsdateum", "error");
+ $this->redirect("Contract", "productchange", ["contract_id" => $id]);
+ }
+
+ $finish_date->setTime(0,0,0);
+ $contract_data["finish_date"] = $finish_date->getTimestamp();
+
+ $contract_cancel_date = clone($finish_date);
+ $contract_cancel_date->modify("-1 day");
+ $contract_cancel_date->setTime(23,59,59);
+ }
+
$require_term = false;
if (array_key_exists(TT_ATTRIB_TERMINATION_REQUIRED_NAME, $product->attributes) && $product->attributes[TT_ATTRIB_TERMINATION_REQUIRED_NAME]->value == 1) {
//var_dump($prod->attributes);
@@ -353,41 +349,124 @@ class ContractController extends mfBaseController
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
}
+ if($contract_cancel_date) {
+ $contract->cancel_date = $contract_cancel_date->getTimestamp();
+ $contract->save();
+ }
+
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $new_contract->id,
+ 'type' => "created_from",
+ 'value' => "productchange",
+ 'text' => "Produkt-/Standortwechsel von Contract ID ".$contract->id
+ ]);
+ $journal->save();
if (is_array($r->links) && count($r->links)) {
- foreach ($r->links as $link_id => $action) {
+ foreach ($r->links as $link_id => $link_data) {
+ $action = $link_data["action"];
+ $cancel_date = false;
+ if($link_data["cancel_date"]) {
+ try {
+ $cancel_date = DateTime::createFromFormat("d.m.Y", $link_data["cancel_date"], new DateTimeZone("Europe/Vienna"));
+ } catch (Exception $e) {
+ $this->layout()->setFlash("Ungültiges Kündigungsdateum", "error");
+ $this->redirect("Contract", "productchange", ["contract_id" => $id]);
+ }
+ }
+
+
$old_link = new ContractLink($link_id);
if (!$old_link->id) continue;
// check if link contains this contract
if ($old_link->contract_id == $contract->id) {
+ $origin_id = $old_link->origin_contract_id;
+ $link_contract_id = $old_link->contract_id;
+
$new_link_contract_id = $new_contract->id;
$new_link_origin_id = $old_link->origin_contract_id;
} elseif ($old_link->origin_contract_id == $contract->id) {
+ $origin_id = $old_link->contract_id;
+ $link_contract_id = $old_link->origin_contract_id;
+
$new_link_contract_id = $old_link->contract_id;
$new_link_origin_id = $new_contract->id;
} else {
continue;
}
- $new_link = ContractLinkModel::create([
- 'contract_id' => $new_link_contract_id,
- 'origin_contract_id' => $new_link_origin_id,
- 'type' => $old_link->type,
- ]);
- if (!$new_link->save()) {
- $this->layout()->setFlash("Konnte neuen Link nicht speichern", "warn");
- }
-
- if ($action == "cancel") {
- $old_link->change_action = "cancel";
- if (!$old_link->save()) {
- $this->layout()->setFlash("Konnte alten Link nicht speichern", "warn");
+ if($action != "cancel" && $old_link->type != "credit") {
+ $new_link = ContractLinkModel::create([
+ 'contract_id' => $new_link_contract_id,
+ 'origin_contract_id' => $new_link_origin_id,
+ 'type' => $old_link->type,
+ ]);
+ if (!$new_link->save()) {
+ $this->layout()->setFlash("Konnte neuen Link nicht speichern", "warn");
}
}
+ if ($action == "cancel") {
+ if($cancel_date) {
+ // insert cancel_date in old contract
+ $lc = new Contract($origin_id);
+ $lc->cancel_date = $cancel_date->getTimestamp();
+ $lc->save();
+ } else {
+ // leave cancellation for later (when finishing upgrade)
+ $old_link->change_action = "cancel";
+ if (!$old_link->save()) {
+ $this->layout()->setFlash("Konnte alten Link nicht speichern", "warn");
+ }
+ }
+
+ }
+
if ($old_link->type == "credit" && $action == "keep") {
- $old_link->change_action = "recreate";
+ // XXX - if we have finish date then recreate credit contract right now
+ if($contract_cancel_date) {
+ $new_credit = ContractModel::createCreditForContract($new_contract);
+ $new_credit->save();
+
+ // create journal for credit
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $new_credit->id,
+ 'type' => "created_from",
+ 'value' => "productchange",
+ 'text' => "Produkt-/Standortwechsel von Contract ID ".$new_link_origin_id
+ ]);
+ $journal->save();
+
+
+ $this->log->debug(print_r($new_credit, true));
+
+ // set cancel date for old credit
+ $old_credit = new Contract($origin_id);
+ $old_credit->cancel_date = $contract_cancel_date->getTimestamp();
+ $old_credit->save();
+
+ // create link to new credit contract
+ $link = ContractLinkModel::create([
+ "contract_id" => $new_credit->id,
+ "origin_contract_id" => $new_contract->id,
+ "type" => "credit"
+ ]);
+ $link->save();
+
+ // create upgrade link from old to new credit contract
+ $link = ContractLinkModel::create([
+ "contract_id" => $new_credit->id,
+ "origin_contract_id" => $origin_id,
+ "type" => "upgrade"
+ ]);
+ $link->save();
+
+ } else {
+ $old_link->change_action = "recreate";
+ $old_link->save();
+ }
+
}
//var_dump($new_link);exit;
@@ -439,82 +518,23 @@ class ContractController extends mfBaseController
$this->redirect("Contract");
}
- $now = date('U');
-
- /*
- * Vorgänger Contracts kündigen
- */
- foreach (ContractLinkModel::search(['contract_id' => $id]) as $link) {
- if (!in_array($link->type, ["upgrade", "downgrade", "relocation", "productchange"])) {
- continue;
- }
-
- $origin = $link->origin;
- $origin->cancel_date = $now;
- $origin->cancel_date_by = $this->me->id;
- $origin->edit_by = $this->me->id;
- if (!$origin->save()) {
- $this->layout()->setFlash("Achtung: Konnte nicht alle Vorgängercontracts kündigen!", "warn");
- }
-
- /*
- * alte Links übernehmen / kündigen
- */
- foreach (ContractLinkModel::search(['type' => "link", 'contract_id' => $origin->id]) as $old_link) {
- // verlinkten Contract kündigen (wenn nicht schon gekündigt)
- if ($old_link->change_action == "cancel" && !$old_link->contract->cancel_date) {
- $old_link->origin->update([
- 'cancel_date' => $now,
- 'cancel_date_by' => $this->me->id,
- 'edit_by' => $this->me->id
- ]);
- $old_link->origin->save();
-
- $old_link->change_action = null;
- $old_link->save();
- }
- }
-
- foreach (ContractLinkModel::search(['type' => "link", 'origin_contract_id' => $origin->id]) as $old_link) {
- // verlinkten Contract kündigen (wenn nicht schon gekündigt)
- if ($old_link->change_action == "cancel" && !$old_link->contract->cancel_date) {
- $old_link->contract->update([
- 'cancel_date' => $now,
- 'cancel_date_by' => $this->me->id,
- 'edit_by' => $this->me->id
- ]);
- $old_link->contract->save();
-
- $old_link->change_action = null;
- $old_link->save();
- }
- }
-
- foreach (ContractLinkModel::search(['type' => "credit", 'contract_id' => $origin->id]) as $old_credit) {
- // verlinkten Contract kündigen (wenn nicht schon gekündigt)
- if ($old_credit->change_action == "recreate" && !$old_credit->contract->cancel_date) {
- $old_credit->origin->update([
- 'cancel_date' => $now,
- 'cancel_date_by' => $this->me->id,
- 'edit_by' => $this->me->id
- ]);
- $old_credit->origin->save();
-
- $old_credit->change_action = null;
- $old_credit->save();
- }
- }
+ $now = new DateTime("now");
+ $now->setTime(0,0,0);
+ $contract->finish_date = $now->getTimestamp();
+ $contract->finish_date_by = $this->me->id;
+ try {
+ $saved = $contract->save();
+ } catch(Exception $e) {
+ $saved = false;
}
-
- $contract->finish_date = $now;
- $contract->finish_date_by = $this->me->id;
- if (!$contract->save()) {
+ if(!$saved) {
$this->layout()->setFlash("Contract konnte nicht gespeichert werden", "error");
$this->redirect("Contract", "view", ['contract_id' => $id]);
}
+
// create Journal
$journal = ContractjournalModel::create([
'contract_id' => $contract->id,
@@ -620,6 +640,10 @@ class ContractController extends mfBaseController
$contract_data['billing_delay'] = (int)$r->billing_delay;
$contract_data['note'] = $r->note;
+ if($r->termination_id) {
+ $contract_data["termination_id"] = $r->termination_id;
+ }
+
if($r->order_date) {
$order_date = new DateTime("@" . $this->dateToTimestamp($r->order_date));
$order_date->setTimezone(new DateTimeZone("Europe/Vienna"));
diff --git a/application/Contract/ContractModel.php b/application/Contract/ContractModel.php
index 7df9d3d30..f1ea89cf0 100644
--- a/application/Contract/ContractModel.php
+++ b/application/Contract/ContractModel.php
@@ -184,6 +184,108 @@ class ContractModel {
return $contract;
}
+
+ public static function createCreditForContract($contract) {
+ $log = mfLoghandler::singleton();
+ $me = new User();
+ $me->loadMe();
+
+ if(!$contract->id) {
+ $log->warning(__METHOD__."(): Invalid Contractqueue object");
+ return false;
+ }
+
+ $product = $contract->product;
+ $owner = $contract->owner;
+
+ if(!$product->id) {
+ $log->warning(__METHOD__."(): Invalid Product");
+ return false;
+ }
+
+ /*
+ * Get credit price from NNE or percentage of sales price
+ */
+ $crediting_partner_id = false;
+ $crediting_partner_rate = false;
+
+ $product_attribs = $product->attributes;
+ if(is_array($product_attribs) && array_key_exists("crediting_partner", $product_attribs) && $product_attribs["crediting_partner"] && is_object($product_attribs["crediting_partner"])) {
+ if($product_attribs["crediting_partner"]->value) {
+ $crediting_partner_id = $product_attribs["crediting_partner"]->value;
+ }
+ if($product_attribs["crediting_rate"]->value) {
+ $crediting_partner_rate = str_replace(",", ".",$product_attribs["crediting_rate"]->value);
+ }
+ }
+
+ // or from netowner if anschluss product
+ if(!$crediting_partner_id && $contract->termination_id) {
+ $crediting_partner_id = $contract->termination->building->network->owner_id;
+ }
+
+ $crediting_partner = new Address($crediting_partner_id);
+ if(!$crediting_partner->id) {
+ $log->error(__METHOD__.": Kein Crediting Partner gefunden für Credit für Contract ID ".$contract->id);
+ return false;
+ }
+
+ // determine price:
+ // either NNE or percentage based, depends on product
+ $crediting_price = $product->price_nne;
+ if($crediting_partner_rate) {
+ $crediting_price = round($contract->price / 100 * $crediting_partner_rate, 4);
+ }
+
+ if(!$crediting_price) return true;
+ $crediting_price *= -1;
+
+ $data = [];
+ $data["orderproduct_id"] = null;
+ $data["owner_id"] = $crediting_partner_id;
+ $data["billingaddress_id"] = null;
+ $data["termination_id"] = null;
+ $data["product_id"] = $contract->product_id;
+ $data["product_name"] = $contract->product_name;
+ $data["product_info"] = $contract->product_info;
+ $data["amount"] = $contract->amount;
+ $data["sla_id"] = $contract->sla_id;
+ $data["product_external"] = $contract->product_external;
+ $data["product_external_id"] = $contract->product_external_id;
+ $data["billing_delay"] = $contract->billing_delay;
+ $data["billing_period"] = $contract->billing_period;
+ $data["contract_term"] = $contract->contract_term;
+ $data["order_date"] = $contract->order_date;
+
+ $data["finish_date"] = $contract->finish_date;
+ $data["finish_date_by"] = $me->id;
+ $data["note"] = null;
+
+
+ // matchcode
+ $owner_address = $owner->street.", ".$owner->zip." ".$owner->city;
+ if($contract->termination_id) {
+ $termination = new Termination($contract->termination_id);
+ $termination_address = $termination->building->street.", ".$termination->building->zip." ".$termination->building->city;
+ $matchcode = $termination_address;
+ } else {
+ $matchcode = $owner_address;
+ }
+
+ $matchcode = $contract->owner->getCompanyOrName()."; $matchcode";
+
+ $data["matchcode"] = $matchcode;
+ $data["price"] = $crediting_price;
+ $data["price_setup"] = 0;
+ $data["price_nne"] = 0;
+ $data["price_nbe"] = 0;
+ $data["vatgroup_id"] = $contract->vatgroup_id;
+
+
+ $credit = ContractModel::create($data);
+
+ return $credit;
+ }
public static function getAll() {
$items = [];
diff --git a/application/Contract/trigger/Finished.php b/application/Contract/trigger/Finished.php
new file mode 100644
index 000000000..bc81bc6ce
--- /dev/null
+++ b/application/Contract/trigger/Finished.php
@@ -0,0 +1,186 @@
+ $value) {
+ if(in_array($name, ["log", "db", "contract", "me"])) {
+ $this->$name = $value;
+ }
+ }
+ }
+
+ /**
+ * Checks Contract if can/must run
+ * return true if it wants to run
+ * @return bool
+ */
+ public function precheck() {
+ $contract = $this->contract;
+ if($contract->finish_date && !$contract->_old_data->finish_date) {
+ // contract was just finished, so we need to run
+ return true;
+ }
+ }
+
+ public function run() {
+ $contract = $this->contract;
+ if($contract->_old_data->finish_date) {
+ var_dump($contract->finish_date, $contract->_old_data->finish_date);
+ return true;
+ }
+ // contract was just finished, so we need to run
+
+ /*
+ * Vorgänger Contracts kündigen
+ */
+ foreach (ContractLinkModel::search(['contract_id' => $contract->id]) as $link) {
+ if (!in_array($link->type, ["upgrade", "downgrade", "relocation", "productchange", "ownerchange"])) {
+ continue;
+ }
+
+ $now = new DateTime("now");
+ $now->setTime(2,0,0);
+
+ $cancel_date = clone($now);
+ $cancel_date->setTime(23,59,59);
+
+ $origin = $link->origin;
+ $origin->cancel_date = $cancel_date->getTimestamp();
+ $origin->cancel_date_by = $this->me->id;
+ $origin->edit_by = $this->me->id;
+ if (!$origin->save()) {
+ throw new Exception("Fehler beim Speichern der Kündigung des Vorgängercontracts!");
+ }
+ // cancel journal
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $origin->id,
+ 'type' => "canceled",
+ 'value' => "",
+ 'text' => ""
+ ]);
+ $journal->save();
+
+
+ /*
+ * alte Links übernehmen / kündigen
+ */
+ foreach (ContractLinkModel::search(['type' => "link", 'contract_id' => $origin->id]) as $old_link) {
+ // verlinkten Contract kündigen (wenn nicht schon gekündigt)
+ if ($old_link->change_action == "cancel" && !$old_link->origin->cancel_date) {
+ $old_link->origin->update([
+ 'cancel_date' => $now->getTimestamp(),
+ 'cancel_date_by' => $this->me->id,
+ 'edit_by' => $this->me->id
+ ]);
+ if(!$old_link->origin->save()) {
+ throw new Exception("Fehler beim Speichern der Kündigung des Vorgängercontracts!");
+ }
+
+ $old_link->change_action = null;
+ $old_link->save();
+
+ // cancel journal
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $old_link->origin->id,
+ 'type' => "canceled",
+ 'value' => "",
+ 'text' => ""
+ ]);
+ $journal->save();
+ }
+ }
+
+ foreach (ContractLinkModel::search(['type' => "link", 'origin_contract_id' => $origin->id]) as $old_link) {
+ // verlinkten Contract kündigen (wenn nicht schon gekündigt)
+ if ($old_link->change_action == "cancel" && !$old_link->contract->cancel_date) {
+ $old_link->contract->update([
+ 'cancel_date' => $now->getTimestamp(),
+ 'cancel_date_by' => $this->me->id,
+ 'edit_by' => $this->me->id
+ ]);
+ //$this->log->debug(print_r($old_link->contract, true));
+ $old_link->contract->save();
+
+ $old_link->change_action = null;
+ $old_link->save();
+
+ // cancel journal
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $old_link->contract->id,
+ 'type' => "canceled",
+ 'value' => "",
+ 'text' => ""
+ ]);
+ $journal->save();
+ }
+ }
+
+ foreach (ContractLinkModel::search(['type' => "credit", 'origin_contract_id' => $origin->id]) as $old_credit) {
+ if ($old_credit->change_action == "recreate" && !$old_credit->contract->cancel_date) {
+ // Alte Gutschrift kündigen und neue anlegen
+ //var_dump($old_credit->contract);
+ $old_credit->contract->update([
+ 'cancel_date' => $now->getTimestamp(),
+ 'cancel_date_by' => $this->me->id,
+ 'edit_by' => $this->me->id
+ ]);
+ $old_credit->contract->save();
+ //var_dump($old_credit->contract);
+ //exit;
+
+ $old_credit->change_action = null;
+ $old_credit->save();
+
+ $new_credit = ContractModel::createCreditForContract($contract);
+ if(!$new_credit->save()) {
+ $this->log->debug(print_r($new_credit, true));
+ throw new Exception("Fehler beim Speichern des neuen Gutschrift Contracts");
+ }
+
+ // create journal for credit
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $new_credit->id,
+ 'type' => "created_from",
+ 'value' => "productchange",
+ 'text' => "Produkt-/Standortwechsel von Contract ID ".$old_credit->contract_id
+ ]);
+ $journal->save();
+
+
+ $this->log->debug(print_r($new_credit, true));
+
+ // create link to new credit contract
+ $link = ContractLinkModel::create([
+ "contract_id" => $new_credit->id,
+ "origin_contract_id" => $contract->id,
+ "type" => "credit"
+ ]);
+ $link->save();
+
+ // create link from old to new credit contract
+ $link = ContractLinkModel::create([
+ "contract_id" => $new_credit->id,
+ "origin_contract_id" => $old_credit->contract_id,
+ "type" => "upgrade"
+ ]);
+ $link->save();
+
+ $journal = ContractjournalModel::create([
+ 'contract_id' => $old_credit->contract_id,
+ 'type' => "canceled",
+ 'value' => "",
+ 'text' => ""
+ ]);
+ $journal->save();
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/application/Contractqueue/ContractqueueModel.php b/application/Contractqueue/ContractqueueModel.php
index 6f195a21a..ee066fa14 100644
--- a/application/Contractqueue/ContractqueueModel.php
+++ b/application/Contractqueue/ContractqueueModel.php
@@ -103,7 +103,7 @@ class ContractqueueModel {
$data["billing_delay"] = $op->billing_delay;
$data["billing_period"] = $op->billing_period;
$data["order_date"] = $order->order_date;
-
+
$data["finish_date"] = $order->finish_date;
$data["finish_date_by"] = 1;
$data["note"] = $order->note;
diff --git a/db/migrations/20240716164608_contract_link_change_changeaction_to_varchar.php b/db/migrations/20240716164608_contract_link_change_changeaction_to_varchar.php
new file mode 100644
index 000000000..730f6ec2c
--- /dev/null
+++ b/db/migrations/20240716164608_contract_link_change_changeaction_to_varchar.php
@@ -0,0 +1,31 @@
+getEnvironment() == "thetool") {
+ $table = $this->table("ContractLink");
+ $table->changeColumn("change_action", "string", ["null" => true, "default" => null, "limit" => 64]);
+ $table->update();
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+
+ public function down(): void
+ {
+ if($this->getEnvironment() == "thetool") {
+
+ }
+
+ if($this->getEnvironment() == "addressdb") {
+
+ }
+ }
+}
diff --git a/scripts/addressdb/update_hausnummer_unit_count.php b/scripts/addressdb/update_hausnummer_unit_count.php
index 892fab0a1..6268522f0 100644
--- a/scripts/addressdb/update_hausnummer_unit_count.php
+++ b/scripts/addressdb/update_hausnummer_unit_count.php
@@ -13,16 +13,13 @@ require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php");
$i = 0;
-foreach(ADBWohneinheitModel::getAll() as $unit) {
- $hausnummer = new ADBHausnummer($unit->hausnummer_id);
- if($hausnummer->id) {
- $unit_count = ADBWohneinheitModel::count(['hausnummer_id' => $unit->hausnummer_id]);
+foreach(ADBHausnummerModel::search(["netzgebiet_id" => true]) as $hausnummer) {
+ $unit_count = ADBWohneinheitModel::count(['hausnummer_id' => $hausnummer->id]);
$hausnummer->unit_count = $unit_count;
if(!$hausnummer->save()) {
echo "error saving hausnummer ".$hausnummer->id."\n";
}
$i++;
- }
}
-echo "Updated $i Wohneinheiten\n";
+echo "Updated $i Hausnummern\n";
diff --git a/scripts/test.php b/scripts/test.php
index 12ce7892b..f692983c3 100644
--- a/scripts/test.php
+++ b/scripts/test.php
@@ -1,6 +1,6 @@
#!/usr/bin/php
id);
define("INTERNAL_USER_USERNAME", $me->username);
-require_once(APPDIR . "Admin/functions/IvtContractImport.php");
-$ownerIdToBillingAddress = [];
-
-$ici = new Admin_IvtContractImport();
-
-$orderproduct = false;
-$orderproduct_id = false;
-
-$ivt_contract = new IvtCustomerProduct(5983);
-
-$ivt_customer = $ivt_contract->customer;
-$ivt_product = $ivt_contract->product;
-
-/*
- * get thetool product from IvtProductMatch
- */
-$productMatch = IvtProductMatchModel::getFirst(["ivt_product_id" => $ivt_contract->pid]);
-if(!$productMatch) {
- echo "Kein Match zu IVT Product " . $ivt_contract->pid . " gefunden. \n";
- exit;
-}
-
-$ip = $productMatch->ivtproduct;
-$product = $productMatch->product;
-
-/*
- * check ivt customer and get Billingaddress
- */
-$billingaddress_id = false;
-
-//var_dump($ivt_contract);exit;
-$customer_check_return = checkIvtCustomer($ivt_contract, $ivt_customer, $product);
-
-
-private function checkIvtCustomer($ivt_contract, $ivt_customer, $product, $doit = false)
- {
- global $ownerIdToBillingAddress;
- $return = [];
- // create customer if not exists
- $ivt_custnum = $ivt_customer->id;
- if (!$ivt_custnum) return false;
-
- // sync billing address
- $owner = AddressModel::getFirst(["customer_number" => $ivt_custnum]);
- if (!$owner) {
- //var_dump($ivt_customer, $ivt_contract);
- die("Address $ivt_custnum not found!");
- }
-
- if(array_key_exists($owner->id, $this->ownerIdToBillingAddress)) {
- return ["billingaddress_id" => $this->ownerIdToBillingAddress[$owner->id]];
- }
-
- $compare_address = $owner;
- $compare_type = "owner";
- $return["billingaddress_id"] = $owner->id;
-
- $order = $this->findOrder($ivt_contract);
- if(!$order) {
- $return["billingaddress_id"] = $owner->id;
- $compare_address = $owner;
- $compare_type = "owner";
- }
-
- // look for billingaddress_id in order and use it
- if ($order && $order->billingaddress_id) {
- $return["billingaddress_id"] = $order->billingaddress_id;
-
- $billingaddress = new Address($order->billingaddress_id);
- if (!$billingaddress->id) {
- die("Billingaddress " . $order->billingaddress_id . " does not exist (order " . $order->id . "; ivt customer $ivt_custnum)");
- }
-
- $compare_address = $billingaddress;
- $compare_type = "billingaddress";
- }
-
-
-
- // if no billingaddress_id in order, compare address of Address and ivt_customer and
- // create new billingaddress if nessecary
-
- if(!$compare_address) {
- die("No Compare address");
- }
-
- $address_update = $this->compareBillingAddresses($ivt_customer, $compare_address);
- if($address_update === true) {
- $return["billingaddress_id"] = $compare_address->id;
- } elseif(is_array($address_update) && count($address_update)) {
- if($compare_type == "billingaddress") {
- // update billingaddress
- $compare_address->update($address_update);
- if(!$compare_address->save()) {
- die("error updateing Billingaddress");
- }
- $this->ownerIdToBillingAddress[$owner->id] = $billingaddress->id;
- $return["billingaddress_id"] = $compare_address->id;
- } else {
- // create billingaddress
- $billingaddress = AddressModel::create($address_update);
- try {
- if(!$billingaddress->save()) {
- var_dump($address_update);
- die("error creating Billingaddress");
- }
- $return["billingaddress_id"] = $billingaddress->id;
- if(!array_key_exists($owner->id, $this->ownerIdToBillingAddress)) {
- $ownerIdToBillingAddress[$owner->id] = $billingaddress->id;
- /*$this->log->debug(__METHOD__.": Creating billing link for owner ".$owner->id." ".$owner->getCompanyOrName()."with billing address ".$billingaddress->id." ".$billingaddress->getCompanyOrName());
- $this->log->debug("OWNER:");
- $this->log->debug(print_r($owner->data, true));
- $this->log->debug("ADDRESS UPDATE:");
- $this->log->debug(print_r($address_update, true));*/
- // create addresslink
- $l = AddressLinkModel::create([
- 'origin_address_id' => $owner->id,
- 'type' => "billing",
- 'address_id' => $billingaddress->id
- ]);
- $l->save();
- }
-
- } catch (Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
- var_dump($address_update);
- exit();
- }
-
- }
-
- }
-
- return $return;
-
- }
-
- private function compareBillingAddresses($ivt_customer, $tool_customer) {
- $owner = $tool_customer;
-
- $new_billing = [];
-
- if ($ivt_customer->company) {
- if (strtolower(trim($ivt_customer->company)) != strtolower(trim($owner->company))) $new_billing["company"] = $ivt_customer->company;
- } else {
- if (strtolower(trim($ivt_customer->firstname)) != strtolower(trim($owner->firstname))) $new_billing["firstname"] = $ivt_customer->firstname;
- if (strtolower(trim($ivt_customer->surname)) != strtolower(trim($owner->lastname))) $new_billing["lastname"] = $ivt_customer->surname;
- }
-
- //if ($ivt_customer->UID != $owner->uid) $new_billing["uid"] = $ivt_customer->UID;
- if (strtolower(trim($ivt_customer->zip)) != strtolower(trim($owner->zip))) $new_billing["zip"] = $ivt_customer->zip;
- if (strtolower(trim($ivt_customer->location)) != strtolower(trim($owner->city))) $new_billing["city"] = $ivt_customer->location;
- if (strtolower(trim($ivt_customer->street . " " . $ivt_customer->housenumber)) != strtolower(trim($owner->street))) $new_billing["street"] = $ivt_customer->street . " " . $ivt_customer->housenumber;
- //if (strtolower(trim($ivt_customer->phone)) != strtolower(trim($owner->phone))) $new_billing["phone"] = $ivt_customer->phone;
- if (strtolower(trim($ivt_customer->email)) != strtolower(trim($owner->email))) {
- if($ivt_customer->email && !$owner->email) {
- $owner->email = strtolower(trim($ivt_customer->email));
- $owner->save();
- } else {
- $new_billing["email"] = $ivt_customer->email;
- }
- }
-
- $billing_type = "";
- $billing_delivery = "";
- if($ivt_customer->payment == 1 && $owner->billing_type != "invoice") {
- $billing_type = "invoice";
- if($owner->billing_type) {
- $new_billing["billing_type"] = "invoice";
- } else {
- $owner->billing_type = "invoice";
- $owner->save();
- }
- } elseif($ivt_customer->payment == 0 && $owner->billing_type != "sepa") {
- $billing_type = "sepa";
- if($owner->billing_type) {
- $new_billing["billing_type"] = "sepa";
- } else {
- $owner->billing_type = "sepa";
- $owner->save();
- }
- } elseif($ivt_customer->paper_invoice == 1 && $owner->billing_delivery != "paper") {
- $billing_delivery = "paper";
- if($owner->billing_delivery) {
- $new_billing["billing_delivery"] = "paper";
- } else {
- $owner->billing_delivery = "paper";
- $owner->save();
- }
- } elseif($ivt_customer->paper_invoice == 0 && $owner->billing_delivery != "email") {
- $billing_delivery = "email";
- if($owner->billing_delivery) {
- $new_billing["billing_delivery"] = "email";
- } else {
- $owner->billing_delivery = "email";
- $owner->save();
- }
- }
-
- //if($ivt_customer->bank_account_bank != $owner->bank_account_bank) $new_billing["bank_account_bank"] = $ivt_customer->bank_account_bank;
- //if($ivt_customer->bank_account_owner != $owner->bank_account_owner) $new_billing["bank_account_owner"] = $ivt_customer->bank_account_owner;
- $iban = strtoupper(trim(str_replace(" ","", $ivt_customer->IBAN)));
- $bic = strtoupper(trim(str_replace(" ","", $ivt_customer->BIC)));
- if ((array_key_exists("billing_type", $new_billing) && $new_billing["billing_type"] == "sepa") || $ivt_customer->payment == 0 && ($iban || $bic)) {
- if ($iban != strtoupper(trim(str_replace(" ","", $owner->bank_account_iban)))) $new_billing["bank_account_iban"] = $iban;
- if ($bic != strtoupper(trim(str_replace(" ","", $owner->bank_account_bic)))) $new_billing["bank_account_bic"] = $bic;
- }
-
- if(array_key_exists("bank_account_bic", $new_billing) && !array_key_exists("bank_account_iban", $new_billing)) {
- $owner->bank_account_bic = $new_billing["bank_account_bic"];
- $owner->save();
- unset($new_billing["bank_account_bic"]);
- }
-
- if(count($new_billing) == 2 && array_key_exists("billing_type", $new_billing) && array_key_exists("billing_delivery", $new_billing)) {
- $owner->billing_type = $billing_type;
- $owner->billing_delivery = $billing_delivery;
- $owner->save();
- return true;
- }
- if(count($new_billing) == 1) {
- if(array_key_exists("billing_type", $new_billing)) {
- $owner->billing_type = $billing_type;
- $owner->save();
- return true;
- }
- if(array_key_exists("billing_delivery", $new_billing)) {
- $owner->billing_delivery = $billing_delivery;
- $owner->save();
- return true;
- }
-
- }
-
-
-
- //$missing_fields = [];
- $create = false;
- foreach(["company", "firstname", "lastname", "street", "zip", "city", "email", "uid", "billing_type", "billing_delivery",
- "bank_account_iban", "bank_account_bic"] as $field) {
- if(!array_key_exists($field, $new_billing)) {
- /*if(!$owner->$field) {
- if($field == "billing_delivery") {
- $new_billing[$field] = "paper";
- } else {
- $new_billing[$field] = "";
- }
-
- } else {
- $new_billing[$field] = $owner->$field;
- }*/
- $new_billing[$field] = $owner->$field;
- } else {
- if($field == "email" && $new_billing["email"] == "dummy@xinon.at") continue;
- $create = true;
- }
- }
-
- /*
- if($create) {
- $billingaddress = AddressModel::create($new_billing);
- //var_dump($billingaddress, $missing_fields);exit;
- if(!$billingaddress->save()) {
- die("Error createing billingaddress\n");
- }
- $return["billingaddress_id"] = $billingaddress->id;
- }*/
-
- if($create) {
- return $new_billing;
- }
-
- return true;
-
- }
\ No newline at end of file
+$contract = new Contract(3088);
+$new_contract = ContractModel::createCreditForContract($contract);
+$new_contract->save();
+var_dump($new_contract);
\ No newline at end of file
|