loadMe(); $data["edit_by"] = $me->id; } return $data; } protected function afterSave() { if($this->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 addVoiceFromContractQueue($cq) { if($cq->voicenumber) { $voicenumbers = []; $json = json_decode($cq->voicenumber); if(is_array($json) && count($json)) { foreach($json as $number) { $number = str_replace("+", "", $number); $voicenumber = VoicenumberModel::getFirst(["number" => $number]); if($voicenumber) { $voicenumbers[] = $voicenumber; } else { // find block $block_id = null; $block = Voicenumberblock::findBlock($number); if($block) { $block_id = $block->id; } $voicenumber = VoicenumberModel::create([ 'voicenumberblock_id' => $block_id, "contract_id" => null, 'active' => 1, 'activated_date' => date('U'), 'routing' => "kolmisoft", 'number' => $number, 'disabled' => 0 ]); $voicenumbers[] = $voicenumber; } } foreach($voicenumbers as $vn) { $vn->contract_id = $this->id; $vn->active = 1; $vn->activated_date = date("U"); $vn->save(); } } } if($cq->voiceplan_id) { $config_values = $this->getProperty("configvalues"); if(is_array($config_values) && array_key_exists("voicenumberblock_voiceplan_id", $config_values)) { $cc_item = $config_values["voicenumberblock_voiceplan_id"]; $cc_item->setContractId($this->id); } else { $cc_item = ContractconfigItemModel::getFirst(["name" => "voicenumberblock_voiceplan_id"]); $cc_item->setContractId($this->id); } //var_dump($cc_item, $cc_item->value); $cc_item->value->set($cq->voiceplan_id); $cc_item->value->save(); } } 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, "create" => $file->create, "edit" => $file->edit ]); $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, "create_by" => $file->create_by, "edit_by" => $file->edit_by, "create" => $file->create, "edit" => $file->edit ]); $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, 'create_by' => $order_journal->create_by, 'edit_by' => $order_journal->edit_by, 'create' => $order_journal->create, 'edit' => $order_journal->edit ]); $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("Contract", $this->id, json_encode(["type" => "cancel_notification"])); $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("Contract", $this->id, json_encode(["type" => "cancel_notification_int"])); $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("Contract", $this->id); $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("Contract", $this->id); $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 createProductchangeContract($new_product_data, $links = [], $options = []) { $contract_cancel_date = null; $me = new User(); $me->loadMe(); $ignore_missing_term = $options["ignore_missing_term"] ?? false; $no_provision_credits = $options["no_provision_credits"] ?? false; $new_contract = clone $this; $linked_contracts = []; foreach($new_product_data as $field => $value) { $new_contract->$field = $value; } /* * Product check */ $product = new Product($new_contract->product_id); if (!$product->id) { throw new Exception("Produkt nicht gefunden."); } $new_contract->product_external = $product->external; $new_contract->product_external_id = $product->external_id; $new_contract->sla_id = $product->sla_id; // finish date if (array_key_exists("finish_date", $new_product_data) && $new_product_data["finish_date"]) { try { $finish_date = DateTime::createFromFormat("d.m.Y", $new_product_data["finish_date"], new DateTimeZone("Europe/Vienna")); } catch (Exception $e) { throw new Exception("Ungültiges Kündigungsdatum"); } $finish_date->setTime(0, 0, 0); $new_contract->finish_date = $finish_date->getTimestamp(); $contract_cancel_date = clone($finish_date); $contract_cancel_date->modify("-1 day"); $contract_cancel_date->setTime(23, 59, 59); } // termination_id $require_term = false; if (array_key_exists(TT_ATTRIB_TERMINATION_REQUIRED_NAME, $product->attributes) && $product->attributes[TT_ATTRIB_TERMINATION_REQUIRED_NAME]->value == 1) { $require_term = true; $termination = new Termination($this->termination_id); if ($ignore_missing_term && (!$new_product_data['termination_id'] || !$termination->id)) { throw new Exception("Produkt erfordert Anschluss."); } } else { $new_contract->termination_id = null; } // lookup credit contract and if it's missing in $r->links if (!$me->is("Admin")) { $credit_links = ContractLinkModel::includesContractId($this->id, ["type" => "credit"]); foreach($credit_links as $credit_link) { if(!$credit_link->contract->isFinished()) continue; $links[$credit_link->id] = [ "action" => "keep" ]; } } // TODO: Contractconfig übernehmen if ($contract_cancel_date) { $this->cancel_date = $contract_cancel_date->getTimestamp(); $this->edit_by = $me->id; //$contract->save(); } /* * Hndle Linked Contracts */ $handled_credit_contract = false; if (is_array($links) && count($links)) { foreach ($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) { throw new Exception("Ungültiges Kündigungsdatum"); } } $old_link = new ContractLink($link_id); if (!$old_link->id) continue; // check if link contains this contract if ($old_link->contract_id == $this->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 == $this->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; } 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, ]);*/ $link_from_id = $new_link_contract_id; if(!$link_from_id) $link_from_id = $new_link_origin_id; $linked_contracts[] = [ "action" => "keep", "link_from" => new Contract($link_from_id), "link_to" => "new_contract", "credit" => null, ]; /*if($new_contract->owner_id == 3997) { var_dump($link_from_id); var_dump($new_link_origin_id, $new_link_contract_id, $old_link);exit; }*/ /*if (!$new_link->save()) { throw new Exception("Konnte neuen Link nicht speichern"); }*/ } if ($action == "cancel") { if ($cancel_date && $contract_cancel_date) { // insert cancel_date in old contract $lc = new Contract($origin_id); $lc->cancel_date = $cancel_date->getTimestamp(); $linked_contracts[] = [ "action" => "cancel", "link_from" => $lc, "link_to" => null, "credit" => null, ]; //$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 (!$no_provision_credits && $old_link->type == "credit" && $action == "keep") { $handled_credit_contract = true; // XXX - if we have finish date then recreate credit contract right now if ($contract_cancel_date) { $new_credit = ContractModel::createCreditForContract($new_contract); if(!$new_credit) { // new product does not require Credit Contract // or if contract was imported from IVT, credit contract cannot be created because of missing termination_id // so creating is manually if($this->imported_from = "ivt") { // get crediting partner $credit_contract = new Contract($origin_id); if($credit_contract->price > 0) { // in case contract and origin are swapped $credit_contract = new Contract($link_contract_id); if($credit_contract->price > 0) { $this->log->warn(__METHOD__.": Unable to create credit contract for product change, because can't determine original crediting contract."); } } if($credit_contract->price < 0) { $crediting_partner_id = $credit_contract->owner_id; $new_credit = ContractModel::createCreditForContract($new_contract, $crediting_partner_id); /*if($new_contract->owner_id != 727) { var_dump($new_credit); exit; }*/ } } } //$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();*/ $linked_contracts[] = [ "action" => "create_credit", "link_from" => $new_contract, "link_to" => $new_credit, ]; $linked_contracts[] = [ "action" => "cancel_credit", "link_from" => $new_contract, "link_to" => $old_credit, ]; } else { $old_link->change_action = "recreate"; //$old_link->save(); } } //var_dump($new_link);exit; } } if(!$no_provision_credits && !$handled_credit_contract) { // there was no credit contract linked before, so try creating one $credit_contract = ContractModel::createCreditForContract($new_contract); if(is_object($credit_contract)) { $linked_contracts[] = [ "action" => "create_credit", "link_from" => $new_contract, "link_to" => $credit_contract, ]; } else { $this->log->warn("Konnte keinen Credit Contract für Produktwechsel erstellen."); } } return [ "new_contract" => $new_contract, "old_contract" => $this, "linked_contracts" => $linked_contracts, ]; } /* * To commit the product change, old and new contract only need to be saved. They are prepared by createProductchangeContract() already * Links need to be created depending on action: * - for action keep: create ContractLink from link_from to link_to * - for action cancel: save link_from (has cancel_date already) * - for action create_credit: save link_to (new credit contract), link link_to (credit) to link_from (new contract) * - for action cancel_credit: save link_to (old credit to cancel), ignore link_from (new contract) * * * */ public function commitProductchangeContract(\Contract $new_contract, $links = []) { //if(!count($links)) return true; if($new_contract->owner_id==3476) return true; $this->startTransaction(); if(!$this->save()) { $this->rollbackTransaction(); return false; } if(!$new_contract->save()) { $this->rollbackTransaction(); return false; } // TODO //$new_contract->copyConfigFromContractId($this->id); $link = ContractLinkModel::create(['contract_id' => $new_contract->id, 'origin_contract_id' => $this->id, 'type' => "upgrade"]); $link->save(); $journal = ContractjournalModel::create(['contract_id' => $new_contract->id, 'type' => "created_from", 'value' => "productchange", 'text' => "Produkt-/Standortwechsel von Contract ID " . $this->id]); $journal->save(); foreach($links as $link) { //var_dump($link);exit; $origin = $link["link_from"]; $to = $link["link_to"]; $action = $link["action"]; if($action == "keep") { if($to == "new_contract") { $to = $new_contract; } //var_dump($origin, $to);exit; if(!is_object($origin) || !is_object($to)) continue; $new_link = ContractLinkModel::create([ 'contract_id' => $to->id, 'origin_contract_id' => $origin->id, 'type' => "link", ]); //var_dump($link, $new_link);exit; if(!$new_link->save()) { $this->rollbackTransaction(); return false; } } } $this->commitTransaction(); return true; var_dump($new_link);exit; var_dump($this); var_dump($new_contract); //var_dump($links); //var_dump($links); foreach($links as $link) { echo var_dump($link["action"]) . "\n
"; echo "LINK FROM"; var_dump($link["link_from"]); echo "LINK TO"; var_dump($link["link_to"]); } exit; } 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"); } // ---- CONTRACT VIEW UTILITY FUNCTIONS START ---- public function getContractDetails($getUrl): array { $contract = $this; $contract->getProperty("billingaddress"); $contract->getProperty("owner"); $contract->getProperty("product"); $contract->getProperty("sla"); $contract->getProperty("finisher"); $contract->getProperty("canceler"); $contract->getProperty("creator"); $contract->getProperty("editor"); $contract->getProperty("vatrate"); $contract->getProperty("configvalues"); $contract->getProperty("orderproduct"); $contract_details = []; $contract_details['matchcode'] = ['label' => 'Matchcode', 'value' => $contract->matchcode]; $contract_details['owner'] = ['label' => 'Kunde', 'value' => $contract->owner->getCompanyOrName()." (".$contract->owner->customer_number.")", 'url' => $getUrl('Address', 'View', ['id' => $contract->owner->id])]; $contract_details['billingaddress'] = ['label' => 'Rechnungsadresse', "value" => ""]; if ($contract->billingaddress_id) { $contract_details['billingaddress']['value'] = $contract->billingaddress->getCompanyOrName()." (".$contract->billingaddress->customer_number.")"; $contract_details['billingaddress']['url'] = $getUrl('Address', 'View', ['id' => $contract->billingaddress->id]); } $productName = $contract->product->name; $contractProductName = $contract->product_name; $productId = $contract->product_id; $contract_details['product'] = ['label' => 'Produkt', 'value' => "$contractProductName".($productName != $contractProductName ? " ($productName)" : "")." [$productId]", 'url' => $getUrl('Product', 'Edit', ['id' => $contract->product_id])]; if ($contract->prduct_info) { $contract_details['product_info'] = ['label' => 'Produktinfo', 'value' => $contract->product_info]; } $contract_details['sla'] = ['label' => 'SLA', 'value' => $contract->sla->name]; $contract_details['external_product'] = ['label' => 'Externes Produkt', 'value' => $contract->product_external ? "Ja" : "Nein"]; $contract_details['amount'] = ['label' => 'Menge', 'value' => Helper::formatNumber($contract->amount, 3)]; $contract_details['price_net'] = ['label' => 'Preis Periodisch Netto', 'value' => "€ " . Helper::formatNumber($contract->price * $contract->amount, 4), 'class' => $contract->price < 0 ? 'text-danger' : null]; if ($contract->vatrate) { $contract_details['price_gross'] = ['label' => 'Preis Periodisch Brutto', 'value' => "€ " . Helper::formatNumber($contract->price * $contract->amount * floatval("1." . intval($contract->vatrate)), 4), 'class' => $contract->price < 0 ? 'text-danger' : null]; } $contract_details['billing_period'] = ['label' => 'Abrechnungsperiode', 'value' => __($contract->billing_period, "billing_period")]; if ($contract->price_setup > 0) { $vatRateMultiplier = $contract->vatrate ? ("1." . intval($contract->vatrate)) : 1; $price_net = Helper::formatNumber($contract->price_setup, 4); $sum_net = Helper::formatNumber($contract->price_setup * $contract->amount, 4); $price_gross = Helper::formatNumber($contract->price_setup * $contract->amount * $vatRateMultiplier, 4); $sum_gross = Helper::formatNumber($contract->price_setup * $contract->amount * $vatRateMultiplier, 4); $contract_details['price_setup'] = ['label' => 'Einrichtungsgebühr', 'value' => "Netto: € {$price_net} (Gesamt: € {$sum_net})\nBrutto: € {$price_gross} (Gesamt: € {$sum_gross})"]; } if ($contract->billing_delay) $contract_details['billing_delay'] = ['label' => 'Abrechnungsverzögerung', 'value' => $contract->billing_delay . " Monate"]; //$contract_details['space1'] = ['label' => "", "value" => ""]; $contract_details['order_date'] = ['label' => 'Bestelldatum', 'value' => date('d.m.Y', $contract->order_date)]; $contract_details['finish_date'] = ['label' => 'Fertigstellung', 'value' => ($contract->finish_date) ? date('d.m.Y', $contract->finish_date) . " (" . $contract->finisher->name . ")" : ""]; $contract_details['cancel_date'] = ['label' => 'Kündigungsdatum', 'value' => ($contract->cancel_date) ? date('d.m.Y', $contract->cancel_date) . " (" . $contract->canceler->name . ")" : ""]; //$contract_details['space2'] = ['label' => "", "value" => ""]; $contract_details['create'] = ['label' => 'Erstellt', 'value' => date('d.m.Y', $contract->create) . " (" . $contract->creator->name . ")"]; $contract_details['edit'] = ['label' => 'Geändert', 'value' => date('d.m.Y', $contract->edit) . " (" . $contract->editor->name . ")"]; return $contract_details; } public function getContractActions($getUrl): array { $contract = $this; $contract_actions = []; $contract_actions['contractconfig'] = ['url' => $getUrl("Contractconfig", "edit", ["contract_id" => $contract->id]), 'class' => 'btn-outline-info', 'icon' => 'far fa-list-dropdown fa-fw', 'text' => 'Konfiguration bearbeiten']; $contract_actions['contractaccessletter'] = ['url' => $getUrl("Contractaccessletter", "view", ["contract_id" => $contract->id]), 'class' => 'btn-outline-success', 'icon' => 'far fa-list-numeric fa-fw', 'text' => 'Zugangsdaten anzeigen']; if ($contract->finish_date && $contract->finish_date < date('U')) { $contract_actions['contractownerchange'] = ['class' => 'btn-outline-secondary', 'icon' => 'far fa-people-arrows fa-fw', 'text' => 'Inhaberwechsel']; $contract_actions['productchange'] = ['url' => $getUrl("Contract", "productchange", ["contract_id" => $contract->id]), 'class' => 'btn-outline-purple', 'icon' => 'far fa-truck-container fa-fw', 'text' => 'Produkt-/Standortwechsel']; $contract_actions['cancel'] = ['url' => $getUrl("Contract", "cancel", ["contract_id" => $contract->id]), 'class' => 'btn-outline-danger', 'icon' => 'far fa-axe fa-fw', 'text' => 'Kündigen']; } else if (!$contract->finish_date) { $contract_actions['contractconfig'] = ['url' => $getUrl("Contract", "finishContract", ['contract_id' => $contract->id]), 'class' => 'btn-success', 'icon' => 'far fa-face-confused fa-fw', 'text' => 'Jetzt fertigstellen', 'confirmText' => 'Jetzt fertigstellen und in Verrechnung geben?']; } return $contract_actions; } public function getContractJournal($getUrl): array { $contract = $this; $contract->getProperty("journals"); $contract->getProperty("orderproduct"); $contract->getProperty("product"); $contract_journal = []; if (is_array($contract->journals) && count($contract->journals)) { foreach ($contract->journals as $j) { $entry = []; $entry['create'] = date('d.m.Y H:i:s', $j->create); $entry['creator'] = $j->creator->name; if ($j->type === "text" || $j->type === "phone") { $entry['icon'] = $j->type === "text" ? "fas fa-comment-dots text-warning " : "fas fa-phone text-warning "; $entry['iconTitle'] = $j->type === "text" ? "Textnachricht" : "Telefonat"; $entry['text'] = $j->text; } else if ($j->type === "file") { $entry['icon'] = "fas fa-download text-primary "; $entry['iconTitle'] = "Datei"; $entry['text'] = "[URL]"; $entry['url'] = $getUrl("File", "download", ["id" => $j->contractfile->file_id]); $entry['urlText'] = $j->contractfile->name; } else if ($j->type === "created_from") { $entry['icon'] = "fas fa-cogs text-secondary "; $entry['iconTitle'] = "Vertrag erstellt"; $entry['textClass'] = "font-italic"; if ($j->value == "manual") { $entry['text'] = "Contract manuell erstellt"; } else if ($j->value == "import") { $entry['text'] = "Contract importiert: " . $j->text; } else if ($j->value == "order") { $entry['text'] = "Vertrag aus Bestellung [URL] erstellt"; $entry['url'] = $getUrl("Order", "", ["id" => $contract->orderproduct->order_id]); $entry['urlText'] = "#" . $contract->orderproduct->order_id; } else if ($j->value == "productchange") { $entry['text'] = "Vertrag erstellt:" . $j->text; } } else if ($j->type === "contract_finished") { $entry['icon'] = "fas fa-flag-checkered text-success "; $entry['iconTitle'] = "Vertrag fertiggestellt"; $entry['text'] = "Vertrag fertiggestelt"; $entry['textClass'] = "font-italic"; } else if ($j->type === "credit_created") { $entry['icon'] = "fas fa-credit-card text-gray "; $entry['iconTitle'] = "Gutschrift"; $entry['text'] = "Gutschrift Vertrag [URL] erstellt"; $entry['textClass'] = "font-italic"; $entry['url'] = $getUrl("Contract", "View", ["contract_id" => $j->value]); $entry['urlText'] = $j->value; } else if ($j->type === "link") { $link = new Contract($j->value); $entry['icon'] = "fas fa-link text-secondary "; $entry['iconTitle'] = "Verknüpfung"; $entry['text'] = "Verknüpfung mit [URL] erstellt"; $entry['textClass'] = "font-italic"; $entry['url'] = $getUrl("Contract", "view", ['contract_id' => $link->id]); $entry['urlText'] = $link->id . " - " . $link->product_name . " - [" . $link->matchcode . "]"; } else if ($j->type === "canceled") { $entry['icon'] = "fas fa-skull-crossbones bg-danger text-white "; $entry['iconTitle'] = "Kündigung"; $entry['textClass'] = "font-italic"; $entry['text'] = "Vertrag gekündigt"; } $contract_journal[] = $entry; } } return $contract_journal; } // ---- CONTRACT VIEW UTILITY FUNCTIONS END ---- }