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"; $this->log->debug(__METHOD__.": Looking for $classname in $filepath"); if(!file_exists($filepath)) { $this->log->debug(__METHOD__.": $filepath not found"); continue; } require_once $filepath; 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; } } } 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 countActiveLinks($with_credit = false) { $links = $this->getProperty("links"); if(is_array($links) && count($links)) { return count($links); } return 0; } 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 addJournalFromOrder() { if(!$this->orderproduct_id) { return true; } $order = $this->getProperty("orderproduct")->order; if(!$order || !$order->id) { return true; } foreach($order->journals as $order_journal) { $journal = ContractjournalModel::create([ 'contract_id' => $this->id, 'type' => "text", 'value' => "", 'text' => $order_journal->text ]); $journal->save(); } return true; } 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 sendProductchangeNotification(Contract $origin) { $tk_tpl = new Layout(); $tk_tpl->setTemplate("Emailtemplates/order/productchange-ticket"); $tpl_vars = [ "contract" => $this, "origin" => $origin ]; foreach($tpl_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 == "files") { $files = ContractFileModel::search(["contract_id" => $this->id]); if($files) { $this->files = $files; return $this->files; } return []; } 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; $data = $this->data; $this->data = new stdClass(); foreach($data as $key => $value) { $this->data->$key = $value; } // 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"); } }