WIP Contract / IVT Import2024-05-23

This commit is contained in:
Frank Schubert
2024-05-23 18:16:41 +02:00
parent 72c406766c
commit ac598e83e9
9 changed files with 472 additions and 117 deletions

View File

@@ -5,7 +5,7 @@ class Admin_IvtContractImport {
private $log;
private $static_ivt_order_match = [];
public function __construct($request) {
public function __construct($request = false) {
$this->request = $request;
$this->log = mfLoghandler::singleton();
@@ -32,12 +32,39 @@ class Admin_IvtContractImport {
561 => false,
11409 => 1222, // x-tec 1842
14192 => 2596
14192 => 2596,
//tourismusverband thermen- & vulkanland
11221 => 1120,
11222 => 1044,
11223 => 1003,
11224 => 1004,
11225 => 1002,
11226 => 999,
11227 => 1000,
2987 => 4126, // Atos
14890 => 3612,
14891 => 3612,
13551 => 2776, // Wolfgang Lipp
14908 => 2776,
13552 => 2055,
10550 => 230, // Anneliese Wabnegg
10551 => 230,
10995 => 1190
];
}
/* TODO: Credit */
/* TODO: Credit */
public function run($doit = false) {
echo "running...<br />\n";
//echo "running...<br />\n";
$data = [];
$data['ignore'] = 0;
$data["contracts"] = [];
@@ -47,7 +74,7 @@ class Admin_IvtContractImport {
$i = 0;
foreach(IvtCustomerProductModel::search(["lasdt_date>", "2023-04-01"], "cid") as $ivt_contract) {
if($i > 1000 && $ivt_contract->cid != $last_cid) break; // only break after the last ivtcontract of this customer
//if($i > 1000 && $ivt_contract->cid != $last_cid) break; // only break after the last ivtcontract of this customer
$last_cid = $ivt_contract->cid;
$i++;
@@ -166,7 +193,14 @@ class Admin_IvtContractImport {
$ignore = true;
}
if($product->billing_period > 1 && $ivt_contract->last_date < "2023-04-08")
// filter cancelled products
/* // disabled weil gibt keine
if($product->billing_period == 1 && $ivt_contract->lastdate < "2024-04-09") {
continue;
}
if($product->billing_period >= 12 && $ivt_contract->lastdate < "2023-06-06") {
continue;
}*/
/*
* Try to match ivt contract to thetool Order
@@ -254,9 +288,11 @@ class Admin_IvtContractImport {
}
if($doit) {
$this->log->debug("Linking new contracts and creating missing matchcodes");
$this->log->debug("Linking new contracts, creating missing matchcodes and adding voip data");
//var_dump($new_contracts[1789]);exit;
foreach($new_contracts as $ivt_customer_id => $contracts) {
$this->addVoipData($ivt_customer_id, $contracts);
if(count($contracts) < 2) continue;
$prev_contracts = [];
$primary_matchcode = false;
@@ -311,7 +347,7 @@ class Admin_IvtContractImport {
}
}
$this->addVoipData($ivt_customer, $customer);
}
return $data;
@@ -591,7 +627,7 @@ class Admin_IvtContractImport {
$found_product++;
}
if($found_product > 1) {
die("Mehr als eine Bestellung für ivt_customer ".$ivt_customer->id." gefunden.\n" . print_r($owner, true));
die("Mehr als eine Bestellung für ivt_customer ".$ivt_customer->id." (ivt contract ".$ivt_contract->id.") gefunden.\n" . print_r($owner, true));
}
}
$order = new Order($order_id);
@@ -621,36 +657,180 @@ class Admin_IvtContractImport {
// return data
}
private function addVoipData($ivt_customer, $customer) {
private function addVoipData($ivt_customer_id, $contracts) {
//$this->log->debug("in addVoipData(): cid ".$ivt_customer_id);
if($ivt_customer_id == 1376) {
$this->log->debug("Not importing reseller voicenumbers for PROMETHEUS - Markus Paar [1376]");
return true;
}
$ported_in = [];
$voicenumbers = [];
// find voice numbers in ivt
foreach(IvtCustomerTelephoneNrModel::search(["cid" => $ivt_customer->id]) as $ivtnum) {
$ivt_num_count = IvtCustomerTelephoneNrModel::count(["cid" => $ivt_customer_id]);
if(!$ivt_num_count) {
$this->log->debug("No voicenumber in ivt for cid ".$ivt_customer_id);
return false;
}
$this->log->debug("$ivt_num_count voicenumbers in ivt for cid ".$ivt_customer_id);
foreach(IvtCustomerTelephoneNrModel::search(["cid" => $ivt_customer_id]) as $ivtnum) {
$number = preg_replace('/^0043/', '43', $ivtnum->number);
if(!$number) return true;
if(!$number) continue;
// find number in block
$voicenumberblock = Voicenumberblock::findBlock($number);
if(!$voicenumberblock) {
$ported_in[] = $number;
continue;
}
if(!$voicenumberblock->isNumberInBlock($number)) {
die("Block für Nummer $number enthält nummer nicht.");
echo "Block für Nummer $number enthält nummer nicht.\n";
exit;
}
$voicenumber = $voicenumberblock->getVoicenumber($number);
if(!$voicenumber) {
die("Nummer $number gehört nicht in Block ".$voicenumberblock->id);
echo "Nummer $number gehört nicht in Block ".$voicenumberblock->id."\n";
exit;
}
$voicenumbers[] = $voicenumber;
}
$voice_contract = false;
foreach($contracts as $contract) {
if(array_key_exists("needs_number", $contract->product->attributes) && $contract->product->attributes["needs_number"] == 1) {
$voice_contract = $contract;
}
}
if(!$voice_contract) {
$voice_contract = $this->createVoiceContract($contracts);
}
//var_dump($voice_contract);exit;
// put all numbers in $all_numbers array
$all_numbers = [];
foreach($voicenumbers as $voicenumber) {
$all_numbers[] = $voicenumber;
}
foreach($ported_in as $voicenumber) {
// create single number if it does not exist
$ported_number = VoicenumberModel::getFirst(["number" => $voicenumber]);
if(!$ported_number) {
$num_data = [];
if($voice_contract->orderproduct_id) {
$num_data["orderproduct_id"] = $voice_contract->orderproduct_id;
}
$ported_number = VoicenumberModel::create([
"voicenumberblock_id" => null,
"number" => $voicenumber,
"port_in_date" => date("U"),
"ported_in" => 1,
"ported_from" => "A1 Telekom Austria",
]);
} else {
die("Importierte Nummer gibts bereits $voicenumber");
}
$all_numbers[] = $ported_number;
}
$contract_new_numbers = [];
// update all numbers
foreach($all_numbers as $voicenumber) {
$voicenumber->contract_id = $voice_contract->id;
$voicenumber->active = 1;
$voicenumber->activated_date = date("U");
$voicenumber->routing = "kolmisoft";
$voicenumber->comment = "IVT Import ".date("Y-m-d");
if(!$voicenumber->save()) {
die("Fehler beim Speichern der neuen Nummer ".$voicenumber->number);
}
$contract_new_numbers[] = $voicenumber->number;
}
if(array_key_exists("voicenumberblock_voicenumber", $voice_contract->configvalues)) {
$confitem = $voice_contract->configvalues["voicenumberblock_voicenumber"];
} else {
$confitem = ContractconfigItemModel::getFirst(["name" => "voicenumberblock_voicenumber"]);
$confitem->setContractId($voice_contract->id);
}
$confitem->value->set($contract_new_numbers);
$confitem->save();
// return voicenumber object
return $voicenumber;
return true;
}
private function createVoiceContract($contracts) {
// find rufnummer only product (residential or business)
$product = new Product(101); // Telefonie (nur Rufnummer - Privat)
$sla_id = 4;
foreach($contracts as $contract) {
if($contract->sla_id < 4) {
$product = new Product(102); // Telefonie (nur Rufnummer - Business)
$sla_id = 3;
}
}
// first contract
$fc = $contracts[0];
$data = [];
$data["orderproduct_id"] = null;
$data["owner_id"] = $fc->owner_id;
$data["billingaddress_id"] = $fc->billingaddress_id;
$data["termination_id"] = null;
$data["product_id"] = $product->id;
$data["product_name"] = "Telefonie (nur Rufnummer)";
$data["product_info"] = null;
$data["amount"] = 1;
$data["sla_id"] = $sla_id;
$data["product_external"] = 0;
$data["product_external_id"] = null;
$data["price"] = $product->price;
$data["price_setup"] = $product->price_setup;
$data["price_nne"] = $product->price_nne;
$data["price_nbe"] = $product->price_nbe;
$data["billing_delay"] = $product->billing_delay;
$data["billing_period"] = $product->billing_period;
$data["order_date"] = $fc->order_date;
$data["finish_date"] = $fc->finish_date;
$data["finish_date_by"] = 1;
$data["note"] = null;
$voice_contract = ContractModel::create($data);
if(!$voice_contract->save()) {
$this->log->error("Unable to create voice contract for cust ".$fc->customer_number);
exit;
}
// link to all $contracts
foreach($contracts as $contract) {
if (ContractLinkModel::getFirst(["contract_id" => $voice_contract->id, "origin_contract_id" => $contract->id])) {
continue;
}
$link = ContractLinkModel::create([
'contract_id' => $voice_contract->id,
'origin_contract_id' => $contract->id,
'type' => 'link'
]);
$link->save();
}
return $voice_contract;
}
private function createAddressFromIvtCustomer(IvtCustomer $cust) {

View File

@@ -1,26 +1,143 @@
<?php
class Admin_IvtCreditImport {
private $request;
public function __construct($request) {
$this->request = $request;
}
public function run($doit = false) {
$i = 0;
foreach(IvtCustomerCreditingModel::getAll() as $cust_cred) {
if($i<200) {$i++; continue;}
var_dump($cust_cred);
var_dump($cust_cred->netowner);
var_dump($cust_cred->customer);
var_dump($cust_cred->crediting_product);
exit;
if(!$cust_cred->customer) continue;
private $log;
private $request;
private $netownerid = [
3805 => 2840,
4941 => 2840,
4909 => 3199,
];
private $cust_cred_ignore = [
2267,
2934
];
public function __construct($request = false) {
$this->request = $request;
$this->log = mfLoghandler::singleton();
}
public function run($doit = false) {
$i = 0;
foreach(IvtCustomerCreditingModel::getAll() as $cust_cred) {
/*if($i > 200) {
continue;
}*/
$i++;
if(in_array($cust_cred->id, $this->cust_cred_ignore)) continue;
/*var_dump($cust_cred);
var_dump($cust_cred->netowner);
var_dump($cust_cred->customer);
var_dump($cust_cred->crediting_product);
exit;*/
if(!$cust_cred->customer) continue;
$ivt_netowner = $cust_cred->netowner;
$ivt_customer = $cust_cred->customer;
$ivt_cred_product = $cust_cred->crediting_product;
$customer = AddressModel::getFirst(["customer_number" => $ivt_customer->id]);
$netowner = AddressModel::getFirst(["customer_number" => $ivt_netowner->id]);
if(array_key_exists($ivt_netowner->id, $this->netownerid)) {
$netowner = AddressModel::getFirst(["customer_number" => $this->netownerid[$ivt_netowner->id]]);
}
if(!$customer) {
$this->log->debug("No Customer ".$ivt_customer->id." cust_cred ".$cust_cred->id);
exit;
}
if(!$netowner) {
$this->log->debug("No netowner ".$ivt_netowner->id);
exit;
}
$contracts = ContractModel::search(["owner_id" => $customer->id]);
// DEBUG: not all contracts imported yet
if(!count($contracts)) {
continue;
}
// use first contract as primary contract
$primary_contract = reset($contracts);
// find more suitable primary contract
foreach($contracts as $contract) {
// only monthly products
if($contract->biling_period > 1) continue;
// no one-off products
if(!$contract->price && $contract->price_setup) continue;
if($contract->termination_id) {
$primary_contract = $contract;
break;
}
if(preg_match('/(dsl|funkinternet|standortgeber|glasfaser|brettljausn)/i', $contract->product->name)) {
$primary_contract = $contract;
break;
}
}
if(!$primary_contract) {
$this->log->debug("No primary contract cust ".$ivt_customer->id);
}
// create Credit Contract
if(!$primary_contract->product_id) {
var_dump($primary_contract);exit;
}
$data = [];
$data["orderproduct_id"] = $primary_contract->orderproduct_id;
$data["product_id"] = $primary_contract->product_id;
$data["product_name"] = $primary_contract->product_name;
$data["product_info"] = $primary_contract->product_info;
$data["amount"] = $primary_contract->amount;
$data["sla_id"] = $primary_contract->sla_id;
$data["product_external"] = $primary_contract->product_external;
$data["product_external_id"] = $primary_contract->product_external_id;
$data["billing_delay"] = $primary_contract->billing_delay;
$data["billing_period"] = $primary_contract->billing_period;
$data["contract_term"] = $primary_contract->contract_term;
$data["order_date"] = $primary_contract->order_date;
$data["finish_date"] = $primary_contract->finish_date;
$data["finish_date_by"] = $primary_contract->finish_date_by;
$data["note"] = $primary_contract->note;
$data["matchcode"] = $cust_cred->comment;
$data["owner_id"] = $netowner->id;
$data["billingaddress_id"] = $netowner->id;
$data["termination_id"] = null;
$data["price"] = $ivt_cred_product->price_excl * -1;
$data["price_setup"] = 0;
$data["price_nne"] = 0;
$data["price_nbe"] = 0;
$cred_contract = ContractModel::create($data);
if(!$cred_contract->save()) {
$this->log->debug("error saving credit contract");
echo "error saving credit contract";
exit;
}
// Link to all Contracts of Customer
foreach($contracts as $contract) {
if (ContractLinkModel::getFirst(["contract_id" => $cred_contract->id, "origin_contract_id" => $contract->id])) {
continue;
}
$link = ContractLinkModel::create([
'contract_id' => $cred_contract->id,
'origin_contract_id' => $contract->id,
'type' => 'link'
]);
$link->save();
}
}
}
}
}

View File

@@ -258,6 +258,7 @@ class Contract extends mfBaseModel {
}
if($name == "configvalues") {
$this->configvalues = [];
foreach($this->getProperty("configgroups") as $group) {
foreach($group->items as $item) {
$this->configvalues[$item->name] = $item;

View File

@@ -3,6 +3,10 @@
class ContractconfigValue extends mfBaseModel {
private $item;
protected function afterSave() {
$this->runAfterSaveHooks();
}
public function set($new_value) {
// explicitly load item, because we might not have an id yet
$item = new ContractconfigItem($this->item_id);
@@ -21,7 +25,7 @@ class ContractconfigValue extends mfBaseModel {
if($item->multiple) {
if(!is_array($new_value)) {
$new_value = [$new_vale];
$new_value = [$new_value];
}
$json_array = [];
@@ -48,6 +52,45 @@ class ContractconfigValue extends mfBaseModel {
return true;
}
public function runAfterSaveHooks() {
$contract = $this->getProperty("item")->contract;
if(!$contract || !$contract->id) {
return false;
}
$folderpath = APPDIR."/Contractconfig/hooks/";
$dir = opendir($folderpath);
while($filename = readdir($dir)) {
if(substr($filename, 0, 1) == ".") {
continue;
}
if($filename == "Contractconfig_Hook.php") continue;
if(substr($filename, -4) != ".php") continue;
$hook_type = basename($filename, ".php");
$classname = "Contractconfig_Hook_$hook_type";
$hook_class_filename = $folderpath.$filename;
require_once $hook_class_filename;
if(!class_exists($classname)) {
continue;
}
$hook = new $classname($contract);
if($hook->isResponsible()) {
$this->log->debug("Running {$classname}->afterSave() for Contract id ".$contract->id);
$hook->afterSave();
if($hook->errors) {
$this->hook_errors = $hook->errors;
return false;
}
}
}
return true;
}
public function getProperty($name) {
if($this->$name == null) {

View File

@@ -1,74 +1,59 @@
<?php
class IvtCreditingProduct extends mfBaseModel {
protected $forcestr = [];
protected $forcestr = [];
/**
* Takes ID or DB row as arguments
* @param id or table row $_
*/
public function __construct($_=NULL) {
$this->log = mfLoghandler::singleton();
$this->data = new stdClass();
$this->table = "crediting_products";
/**
* Takes ID or DB row as arguments
* @param id or table row $_
*/
public function __construct($_ = NULL) {
$this->log = mfLoghandler::singleton();
$this->data = new stdClass();
$this->table = "crediting_products";
$this->db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
$this->db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
if(is_numeric($_)) {
$this->fetch($_);
} elseif(is_object($_)) {
$this->load($_);
}
}
public function save() {
return true;
}
public function getProperty($name) {
if($this->$name == null) {
if($name == "product") {
$ivtproduct = new IvtProduct($this->pid);
if($ivtproduct->id) {
$this->ivtproduct = $ivtproduct;
if(is_numeric($_)) {
$this->fetch($_);
} elseif(is_object($_)) {
$this->load($_);
}
return $this->ivtproduct;
}
if($name == "customer") {
$ivtcustomer = new IvtCustomer($this->cid);
if($ivtcustomer->id) {
$this->ivtcustomer = $ivtcustomer;
}
return $this->ivtcustomer;
}
$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;
}
public function save() {
return true;
}
public function getProperty($name) {
if($this->$name == null) {
public function __debugInfo() {
$vars = get_object_vars($this);
if(is_object($vars['db'])) $vars['db'] = "object(FronkDB)";
if(is_object($vars['log'])) $vars['log'] = 'object(mfLoghandler)';
return $vars;
}
$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;
}
public function __debugInfo() {
$vars = get_object_vars($this);
if(is_object($vars['db'])) $vars['db'] = "object(FronkDB)";
if(is_object($vars['log'])) $vars['log'] = 'object(mfLoghandler)';
return $vars;
}
}

View File

@@ -9,7 +9,7 @@ class IvtCustomerTelephoneNrModel {
$db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
if(!$order) {
$order = "id";
$order = "cid,number";
}
$res = $db->select("customer_telephone_nr", "*", "1=1 ORDER BY $order");
@@ -25,7 +25,7 @@ class IvtCustomerTelephoneNrModel {
$db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
$where = self::getSqlFilter($filter);
$res = $db->select("customer_telephone_nr", "*", "$where ORDER BY id LIMIT 1");
$res = $db->select("customer_telephone_nr", "*", "$where ORDER BY cid,number LIMIT 1");
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new IvtCustomerTelephoneNr($data);
@@ -42,7 +42,7 @@ class IvtCustomerTelephoneNrModel {
$db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
$where = self::getSqlFilter($filter);
$sql = "SELECT COUNT(*) cnt FROM customer_telephone_nr WHERE $where ORDER by id";
$sql = "SELECT COUNT(*) cnt FROM customer_telephone_nr WHERE $where";
$res = $db->query($sql);
if($db->num_rows($res)) {
@@ -57,7 +57,7 @@ class IvtCustomerTelephoneNrModel {
$db = FronkDB::singleton(IVT_DBHOST, IVT_DBUSER, IVT_DBPASS, IVT_DBNAME);
$where = self::getSqlFilter($filter);
$sql = "SELECT * FROM customer_telephone_nr WHERE $where ORDER by cid,pid,sid,id";
$sql = "SELECT * FROM customer_telephone_nr WHERE $where ORDER by cid,number";
mfLoghandler::singleton()->debug($sql);
if(is_array($limit) && count($limit)) {

View File

@@ -47,11 +47,11 @@ class Voicenumber extends mfBaseModel {
public function afterSave() {
// TODO: Move to some ContractConfig add number function
// if contract_id is given, add number to contract
if($this->contract_id) {
if(is_array($this->contract->configvalues) && array_key_exists("voicenumberblock_voicenumber", $this->contract->configvalues)) {
$cc_item = $this->contract->configvalues["voicenumberblock_voicenumber"];
$contract = new Contract($this->contract_id);
if(is_array($contract->configvalues) && array_key_exists("voicenumberblock_voicenumber", $contract->configvalues)) {
$cc_item = $contract->configvalues["voicenumberblock_voicenumber"];
} else {
$cc_item = ContractconfigItemModel::getFirst(["name" => "voicenumberblock_voicenumber"]);
$cc_item->setContractId($this->contract_id);
@@ -72,7 +72,7 @@ class Voicenumber extends mfBaseModel {
}
// if contract_id was changed, remove number from old contract
if($this->_old_data->contract_id > 0 && $this->_old_data->contract_id != $this->contract_id) {
if(property_exists($this->_old_data, "contract_id") && $this->_old_data->contract_id > 0 && $this->_old_data->contract_id != $this->contract_id) {
$old_contract = new Contract($this->_old_data->contract_id);
$cc_item = $old_contract->configvalues["voicenumberblock_voicenumber"];
$numbers_json = $cc_item->value->json;
@@ -89,7 +89,7 @@ class Voicenumber extends mfBaseModel {
}
}
} elseif($this->_old_data->contract_id > 0) {
} elseif(property_exists($this->_old_data, "contract_id") && $this->_old_data->contract_id > 0) {
// removed contract_id, so remove number from old contract
$old_contract = new Contract($this->_old_data->contract_id);
$cc_item = $old_contract->configvalues["voicenumberblock_voicenumber"];

View File

@@ -0,0 +1,29 @@
#!/usr/bin/php
<?php
require("../../config/config.php");
define('FRONKDB_SQLDEBUG',false);
error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED));
require_once(LIBDIR."/mvcfronk/mfRouter/mfRouter.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseModel.php");
require_once(LIBDIR."/mvcfronk/mfBase/mfBaseController.php");
$me = new User(1);
define("INTERNAL_USER_ID", $me->id);
require_once(APPDIR."Admin/functions/IvtContractImport.php");
require_once(APPDIR."Admin/functions/IvtCreditImport.php");
echo "Import Contracts from IVT\n";
$import = new Admin_IvtContractImport();
$data = $import->run(1);
exit;
echo "Import Credit from IVT\n";
$import = new Admin_IvtCreditImport();
$data = $import->run(1);