Contractjournal finished & Started Contractconfig Hooks for Provisioning Workflow

This commit is contained in:
Frank Schubert
2023-02-24 15:50:28 +01:00
parent aa373b5f4e
commit 3210981994
21 changed files with 562 additions and 279 deletions

View File

@@ -192,7 +192,7 @@
<?php if(is_array($address->contracts) && count($address->contracts)): ?>
<ul class="list-group list-group-flush">
<?php foreach($address->contracts as $contract): ?>
<li class="list-group-item"><a href="<?=self::getUrl("Contract", "View", ["id" => $contract->id])?>"><?=$contract->product_name?> [<?=$contract->matchcode?>]</a> (<?=($contract->finish_date) ? "Fertigstellung: ".date('d.m.Y', $contract->finish_date) : ""?>)</li>
<li class="list-group-item"><a href="<?=self::getUrl("Contract", "View", ["id" => $contract->id])?>"><?=$contract->product_name?> [<?=$contract->matchcode?>]</a> <span class='text-secondary'><?=($contract->finish_date) ? "Fertigstellung: ".date('d.m.Y', $contract->finish_date) : "in Herstellung"?></span></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>

View File

@@ -354,9 +354,33 @@
});
$('#product_id').on("autocomplete.select", function(evt, item) {
if(item && item.value === 0) {
$('#product_id').autoComplete('set', null);
if(item) {
if(item.value === 0) {
$('#product_id').autoComplete('set', null);
return;
}
product_id = item.value;
$.get("<?=self::getUrl("Product","api")?>", {
do: "getProduct",
"product_id": product_id
},
function(success) {
if(success.status != "OK") return;
p = success.result.product;
$("#price").val(p.price);
$("#price_setup").val(p.price_setup);
$("#price_nne").val(p.price_nne);
$("#price_nbe").val(p.price_nbe);
$("#billing_delay").val(p.billing_delay);
$("#billing_period").val(p.billing_period);
},
"json"
);
}
});
// product autocomplete

View File

@@ -224,32 +224,84 @@
<div class="row justify-content-center">
<div class="col-8">
<table class="table table-striped table-sm">
<table class="table table-striped table-sm journal">
<?php foreach($contract->journals as $j): ?>
<tr>
<td style="white-space: nowrap" class="text-monospace"><?=date("d.m.Y H:i", $j->create)?> (<?=$j->creator?>)</td>
<td style="width: 100%">
<?php if($j->type == "text"):?>
<?=self::strtrim(str_replace(["\n", "\r", "\t"]," ", $j->text), 128)?>
<?php elseif($j->type == "phone"): ?>
<i class="fas fa-phone text-white bg-warning p-1"></i> <?=self::strtrim(str_replace(["\n", "\r", "\t"]," ", $j->text), 128)?>
<?php elseif($j->type == "file"): ?>
<?php if($j->type == "text" || $j->type == "phone"):?>
<td><i class="fas <?=($j->type == "text") ? "fa-align-left bg-success" : "fa-phone bg-success"?> text-white p-1"></i></td>
<?php if(strlen($j->text) > 120): ?>
<td style="width: 100%" class="pointer" onclick="toggleTruncatedJournalText(<?=$j->id?>)">
<span id="truncated-<?=$j->id?>"><i class="fas fa-caret-right"></i> <?=self::strtrim(str_replace(["\n", "\r", "\t"]," ", $j->text), 120)?></span>
<span id="fulltext-<?=$j->id?>" class="hidden"><?=nl2br(htmlentities($j->text))?></span>
</td>
<?php else: ?>
<td style="width: 100%">
<?=str_replace(["\n", "\r", "\t"]," ", $j->text)?>
</td>
<?php endif; ?>
</td>
<?php elseif($j->type == "file"): ?>
<td><i class="fas fa-download bg-primary text-white p-1"></i></td>
<td style="width: 100%">
<?php if($j->text): ?>
<?=self::strtrim(str_replace(["\n", "\r", "\t"]," ", $j->text), 128)?><br />
<?php endif; ?>
<a class="text-monospace" href="<?=self::getUrl("File", "download", ["id" => $j->contractfile->file_id])?>"> <i class="fas fa-download"></i> <?=$j->contractfile->name?></a>
<?php elseif($j->type == "created_from"): ?>
<?php if($j->value == "manual"): ?>
<em>Vertrag manuell angelegt.</em>
<?php endif; ?>
<a class="text-monospace" href="<?=self::getUrl("File", "download", ["id" => $j->contractfile->file_id])?>"><?=$j->contractfile->name?></a>
</td>
<?php elseif($j->type == "created_from"): ?>
<td><i class="fas fa-cogs text-secondary pl-1"></i></td>
<td style="width: 100%">
<?php if($j->value == "manual"): ?>
<em>Vertrag manuell angelegt</em>
<?php endif; ?>
</td>
</td>
<?php elseif($j->type == "link"): ?>
<?php $link = new Contract($j->value); ?>
<td><i class="fas fa-link text-secondary pl-1"></i></td>
<td style="width: 100%"><em>Verknüpfung mit <a href="<?=self::getUrl("Contract", "view", ['contract_id' => $link->id])?>"><?=$link->id?> - <?=$link->product_name?> [<?=$link->matchcode?>]</a> erstellt</em></td>
<?php endif; ?>
<td style="white-space: nowrap">
<a href="<?=self::getUrl("Contractjournal", "edit", ["journal_id" => $j->id])?>" title="Journaleintrag bearbeiten"><i class="fas fa-edit"></i></a>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan="4">
<div class="ml-3"><button type="button" class="btn btn-sm btn-info" onclick="$('#new-journal').toggle()"><i class="fas fa-plus"></i> Journaleintrag hinzufügen</button></div>
<div id="new-journal" class="card-body hidden border-top mt-2">
<form method="post" action="<?=self::getUrl("Contractjournal", "save")?>" enctype="multipart/form-data">
<input type="hidden" name="contract_id" value="<?=$contract->id?>">
<label for="new_journal_type" class="form-label">Typ</label>
<select name="type" id="new_journal_type" class="form-control mb-2">
<option value="phone">Telefongespräch</option>
<option value="text">Kommentar</option>
<option value="file">Dateiupload</option>
</select>
<label for="new_journal_text" class="form-label">Text</label>
<textarea name="text" id="new_journal_text" class="form-control mb-2" style="height:120px;"></textarea>
<div id="new-journal-file-container" class="hidden">
<label for="new_journal_file" class="form-label">Dateianhang</label>
<input type="file" name="journal_file" id="new_journal_file" class="form-control mb-2" />
</div>
<button class="btn btn-sm btn-primary" type="submit"><i class="fas fa-save mr-1"></i> Speichern</button>
</form>
</div>
</td>
</tr>
</table>
</div>
</div>
@@ -257,11 +309,11 @@
</div>
<?php endif; ?>
<?php if((is_array($contract->linkFrom) && count($contract->linkFrom)) || (is_array($contract->linkTo) && count($contract->linkTo))): ?>
<div class="card border-top-success">
<div class="card-body">
<h4>Verknüpfte Verträge <small><a href="<?=self::getUrl("Contract", "add", ["origin_contract_id" => $contract->id])?>"><i class="fas fa-plus"></i>Neuen Contract anlegen</a></small></h4>
<?php if((is_array($contract->linkFrom) && count($contract->linkFrom)) || (is_array($contract->linkTo) && count($contract->linkTo))): ?>
<table class="table table-striped table-sm table-bordered table-hover">
<tr>
<th>Kunde</th>
@@ -307,9 +359,10 @@
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<div class="card">
<div class="card-body">
@@ -321,4 +374,21 @@
</div>
</div>
<script>
$(document).ready(function () {
$('#new_journal_type').change(function() {
if($('#new_journal_type').val() == "file") {
$('#new-journal-file-container').show();
} else {
$('#new-journal-file-container').hide();
}
});
});
function toggleTruncatedJournalText(id) {
$("#truncated-" + id).toggle();
$("#fulltext-" + id).toggle();
}
</script>
<?php include(realpath(dirname(__FILE__)."/../../$mfLayoutPackage")."/footer.php"); ?>

View File

@@ -27,7 +27,7 @@
</div>
</div>
<div class="card">
<div class="card border-top-success">
<div class="card-body">
<h3 class="text-center mb-3"><?=$contract->product_name?> (<?=$contract->id?>)</h3>
@@ -53,7 +53,7 @@
</div>
<div class="card">
<div class="card border-top-info">
<div class="card-body">
<h4 class="text-center mb-3">Konfiguration bearbeiten</h4>
<?php if(is_array($groups) && count($groups)): ?>

View File

@@ -45,163 +45,181 @@
</div>
<?php if(is_array($configgroups) && count($configgroups)): ?>
<div class="row">
<?php foreach($configgroups as $group): ?>
<h4>Gruppe <?=$group->name?> <small><a href="#" onclick="$('#item-form-<?=$group->id?>').toggle()"><i class="fas fa-plus"></i> Neues Element erstellen</a></small></h4>
<div class="card hidden" id="item-form-<?=$group->id?>">
<div class="card-body">
<form method="post" action="<?=self::getUrl("ContractconfigItem", "save")?>">
<input type="hidden" name="group_id" value="<?=$group->id?>" />
<div class="p-2 <?=($i % 2 == 0) ? "bg-light" : ""?>">
<div class="row col">
<h5>Neues Config Element</h5>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="item_new_name">Name <small class="text-monospace">[a-z0-9._-]</small></label>
<input type="text" class="form-control" id="item_new_name" name="name" value="" />
<div class="col-6 border pb-1">
<h4><?=$group->name?> <small><a href="#" onclick="$('#item-form-<?=$group->id?>').toggle(); return false;"><i class="fas fa-plus"></i> Neues Element erstellen</a></small></h4>
<div class="card hidden" id="item-form-<?=$group->id?>">
<div class="card-body">
<form method="post" action="<?=self::getUrl("ContractconfigItem", "save")?>">
<input type="hidden" name="group_id" value="<?=$group->id?>" />
<div class="p-2 <?=($i % 2 == 0) ? "bg-light" : ""?>">
<div class="row col">
<h5>Neues Config Element</h5>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_new_type">Datentyp</label>
<select class="form-control" id="item_new_type" name="type" onchange='toggleTypedata("new")'>
<option value="string">String</option>
<option value="int">Ganzzahl</option>
<option value="decimal">Dezimalzahl</option>
<option value="enum">Auswahl</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="typedata_new">
<div class="enum hidden">
<label for="item_new_data">Auswahldaten (1 Element pro Zeile)</label>
<textarea class="form-control" style="height: 128px" id="item_new_data" name="data"></textarea>
</div>
<div class="pattern">
<label for="item_new_pattern">Regex Pattern</label>
<input type="text" class="form-control" id="item_new_pattern" name="pattern" value="" />
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<div class="form-group">
<label for="item_new_displayname">Anzeigename</label>
<input type="text" class="form-control" id="item_new_displayname" name="displayname" value="" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_new_description">Beschreibung</label>
<input type="text" class="form-control" id="item_new_description" name="description" value="" />
</div>
</div>
</div>
<div class="form-group row">
<div class="col">
<input type="submit" class="btn btn-primary" value="Speichern" />
</div>
</div>
</div>
</form>
</div>
</div>
<?php if(is_array($group->items) && count($group->items)): ?>
<?php $i = 0; foreach($group->items as $item): ?>
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action" onclick="$('#item-edit-<?=$item->id?>').toggle()"><span class="text-monospace text-pink"><?=$item->name?></span> - <?=$item->displayname?> [<?=$item->type?>]</a>
<div class="card hidden" id="item-edit-<?=$item->id?>">
<div class="card-body">
<form method="post" action="<?=self::getUrl("ContractconfigItem", "save")?>">
<input type="hidden" name="item_id" value="<?=$item->id?>" />
<input type="hidden" name="group_id" value="<?=$group->id?>" />
<div class="p-2 <?=($i % 2 == 0) ? "bg-light" : ""?>">
<div class="row">
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_name">Name <small class="text-monospace">[a-z0-9._-]</small></label>
<input type="text" class="form-control" id="item_<?=$item->id?>_name" name="name" value="<?=$item->name?>" />
</div>
<div class="row">
<div class="col-md-1">
<div class="form-group">
<label for="item_new_<?=$item->id?>_order">Sortierung</label>
<input type="text" class="form-control" id="item_new_<?=$item->id?>_order" name="order" value="" />
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_type">Datentyp</label>
<select class="form-control" id="item_<?=$item->id?>_type" name="type" onchange="toggleTypedata(<?=$item->id?>)">
<option value="string" <?=($item->type == "string") ? "selected='selected'" : ""?>>String</option>
<option value="int" <?=($item->type == "int") ? "selected='selected'" : ""?>>Ganzzahl</option>
<option value="decimal" <?=($item->type == "decimal") ? "selected='selected'" : ""?>>Dezimalzahl</option>
<option value="enum" <?=($item->type == "enum") ? "selected='selected'" : ""?>>Auswahl</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="typedata_<?=$item->id?>">
<div class="enum <?=($item->type != "enum") ? "hidden" : ""?>">
<label for="item_<?=$item->id?>_data">Auswahldaten (1 Element pro Zeile)</label>
<textarea class="form-control" style="height: 128px" id="item_<?=$item->id?>_data" name="data"><?=$item->typedata?></textarea>
</div>
<div class="pattern <?=($item->type != "string") ? "hidden" : ""?>">
<label for="item_<?=$item->id?>_pattern">Regex Pattern</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_pattern" name="pattern" value="<?=$item->pattern?>" />
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_displayname">Anzeigename</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_displayname" name="displayname" value="<?=$item->displayname?>" />
</div>
<div class="col-md-3">
<div class="form-group">
<label for="item_new_<?=$group->id?>_name">Name <small class="text-monospace">[a-z0-9._-]</small></label>
<input type="text" class="form-control" id="item_new_<?=$group->id?>_name" name="name" value="" />
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_description">Beschreibung</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_description" name="description" value="<?=$item->description?>" />
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_new_<?=$group->id?>_type">Datentyp</label>
<select class="form-control" id="item_new_<?=$group->id?>_type" name="type" onchange='toggleTypedata("new_<?=$group->id?>"); return false;'>
<option value="string">String</option>
<option value="int">Ganzzahl</option>
<option value="decimal">Dezimalzahl</option>
<option value="enum">Auswahl</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="typedata_new_<?=$group->id?>">
<div class="enum hidden">
<label for="item_new_<?=$group->id?>_data">Auswahldaten (1 Element pro Zeile)</label>
<textarea class="form-control" style="height: 128px" id="item_new_<?=$group->id?>_data" name="data"></textarea>
</div>
<div class="pattern">
<label for="item_new_pattern">Regex Pattern</label>
<input type="text" class="form-control" id="item_new_<?=$group->id?>_pattern" name="pattern" value="" />
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-11 float-left">
<input type="submit" class="btn btn-primary" value="Speichern" />
</div>
<div class="form-group row">
<div class="col-md-4">
<div class="form-group">
<label for="item_new_<?=$group->id?>_displayname">Anzeigename</label>
<input type="text" class="form-control" id="item_new_<?=$group->id?>_displayname" name="displayname" value="" />
</div>
<div class="col-md-1 float-right">
<small><a class="text-danger" href="<?=self::getUrl("Contractconfig", "deleteItem", ['id' => $item->id])?>" onclick="if(!confirm('Attribut wirklich löschen?')) return false;"><i class="fas fa-trash-alt"></i> löschen</a></small>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_new_<?=$group->id?>_description">Beschreibung</label>
<input type="text" class="form-control" id="item_new_<?=$group->id?>_description" name="description" value="" />
</div>
</div>
</div>
<div class="form-group row">
<div class="col">
<input type="submit" class="btn btn-primary" value="Speichern" />
</div>
</div>
</form>
</div>
</div>
</form>
</div>
</div>
<?php $i++; endforeach; ?>
<?php endif; ?>
<?php $i++; endforeach; ?>
<?php if(is_array($group->items) && count($group->items)): ?>
<?php $i = 0; foreach($group->items as $item): ?>
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action bg-soft-warning" onclick="$('#item-edit-<?=$item->id?>').toggle(); return false;"><i class="fas fa-caret-right pr-1"></i> <?=($item->order) ? $item->order : ""?> <span class="text-monospace bg-purple text-white ml-1 p-1"><?=$item->name?></span> - <?=$item->displayname?> [<?=$item->type?>]</a>
<div class="card hidden" id="item-edit-<?=$item->id?>">
<div class="card-body">
<form method="post" action="<?=self::getUrl("ContractconfigItem", "save")?>">
<input type="hidden" name="item_id" value="<?=$item->id?>" />
<input type="hidden" name="group_id" value="<?=$group->id?>" />
<div class="p-2 <?=($i % 2 == 0) ? "bg-light" : ""?>">
<div class="row">
</div>
<div class="row">
<div class="col-md-1">
<div class="form-group">
<label for="item_<?=$item->id?>_order">Sortierung</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_order" name="order" value="<?=$item->order?>" />
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label for="item_<?=$item->id?>_name">Name <small class="text-monospace">[a-z0-9._-]</small></label>
<input type="text" class="form-control" id="item_<?=$item->id?>_name" name="name" value="<?=$item->name?>" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_type">Datentyp</label>
<select class="form-control" id="item_<?=$item->id?>_type" name="type" onchange="toggleTypedata(<?=$item->id?>)">
<option value="string" <?=($item->type == "string") ? "selected='selected'" : ""?>>String</option>
<option value="int" <?=($item->type == "int") ? "selected='selected'" : ""?>>Ganzzahl</option>
<option value="decimal" <?=($item->type == "decimal") ? "selected='selected'" : ""?>>Dezimalzahl</option>
<option value="enum" <?=($item->type == "enum") ? "selected='selected'" : ""?>>Auswahl</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="typedata_<?=$item->id?>">
<div class="enum <?=($item->type != "enum") ? "hidden" : ""?>">
<label for="item_<?=$item->id?>_data">Auswahldaten (1 Element pro Zeile)</label>
<textarea class="form-control" style="height: 128px" id="item_<?=$item->id?>_data" name="data"><?=$item->typedata?></textarea>
</div>
<div class="pattern <?=($item->type != "string") ? "hidden" : ""?>">
<label for="item_<?=$item->id?>_pattern">Regex Pattern</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_pattern" name="pattern" value="<?=$item->pattern?>" />
</div>
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_displayname">Anzeigename</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_displayname" name="displayname" value="<?=$item->displayname?>" />
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="item_<?=$item->id?>_description">Beschreibung</label>
<input type="text" class="form-control" id="item_<?=$item->id?>_description" name="description" value="<?=$item->description?>" />
</div>
</div>
</div>
<div class="form-group row">
<div class="col-md-11 float-left">
<input type="submit" class="btn btn-primary" value="Speichern" />
</div>
<div class="col-md-1 float-right">
<small><a class="text-danger" href="<?=self::getUrl("Contractconfig", "deleteItem", ['id' => $item->id])?>" onclick="if(!confirm('Attribut wirklich löschen?')) return false;"><i class="fas fa-trash-alt"></i> löschen</a></small>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<?php $i++; endforeach; ?>
<?php endif; ?>
</div>
<?php $i++; endforeach; ?>
</div>
<?php else: ?>
<i>Keine Configgruppen gefunden</i>
<?php endif; ?>

View File

@@ -7,11 +7,11 @@
<ol class="breadcrumb m-0">
<li class="breadcrumb-item"><a href="<?=self::getUrl("Dashboard")?>"><?=MFAPPNAME_SLUG?></a></li>
<li class="breadcrumb-item"><a href="<?=self::getUrl("Voicenumberblock")?>">Rufnummernblöcke</a></li>
<li class="breadcrumb-item"><a href="<?=self::getUrl("Voicenumberblock")?>#block_id=<?=$number->block->id?>"><?=$number->block->number_first?> - <?=$number->block->number_last?></a></li>
<li class="breadcrumb-item active"><?=$number->getFullNumber()?> bearbeiten</li>
<li class="breadcrumb-item"><a href="<?=self::getUrl("Voicenumberblock")?>#block_id=<?=$number->block->id?>"><?=$number->block->first?> - <?=$number->block->last?></a></li>
<li class="breadcrumb-item active"><?=$number->number?> bearbeiten</li>
</ol>
</div>
<h4 class="page-title">Rufnummer <?=$number->getFullNumber()?></h4>
<h4 class="page-title">Rufnummer <?=$number->number?></h4>
</div>
</div>
</div>
@@ -116,10 +116,10 @@
<select name="disabled_reason" class="form-control">
<option></option>
<option value="ported_out" <?=($number->disabled_reason == "ported_out") ? "selected='selected'" : ""?>>Zu neuem Provider portiert</option>
<option value="ported_back">Zum Anker zurückportiert</option>
<option value="reserved">Reserviert</option>
<option value="legacy">Legacy</option>
<option value="damaged">Kaputt</option>
<option value="ported_back" <?=($number->disabled_reason == "ported_back") ? "selected='selected'" : ""?>>Zum Anker zurückportiert</option>
<option value="reserved" <?=($number->disabled_reason == "reserved") ? "selected='selected'" : ""?>>Reserviert</option>
<option value="legacy" <?=($number->disabled_reason == "legacy") ? "selected='selected'" : ""?>>Legacy</option>
<option value="damaged" <?=($number->disabled_reason == "damaged") ? "selected='selected'" : ""?>>Kaputt</option>
</select>
</div>
</div>

View File

@@ -110,9 +110,9 @@
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->name?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->countrycode?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->areacode?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->base?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->getFirst()?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->getLast()?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->short_prefix?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->first?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->last?></td>
<td onclick="toggleBlock(<?=$block->id?>)"><?=$block->comment?></td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<a href="<?=self::getUrl("Voicenumberblock", "edit", ["id" => $block->id])?>"><i class="far fa-edit" title="Bearbeiten"></i></a>

View File

@@ -3,7 +3,7 @@
?>
<div class="card">
<div class="card-body">
<h4 class="header-title">Rufnummern <?=$block->countrycode?><?=$block->areacode?><?=$block->getFirst()?> - <?=$block->countrycode?><?=$block->areacode?><?=$block->getLast()?></h4>
<h4 class="header-title">Rufnummern <?=$block->countrycode?> <?=$block->areacode?> <?=$block->short_first?> - <?=$block->countrycode?> <?=$block->areacode?> <?=$block->short_last?></h4>
<table class="table table-striped table-sm">
<tr>
<th>Nummer</th>
@@ -14,10 +14,10 @@
<th>Entsperrung</th>
<th></th>
</tr>
<?php $i = 0; foreach(range($block->getFirst(), $block->getLast()) as $number): ?>
<?php $num = null; $num = VoicenumberModel::getFirst(['voicenumberblock_id' => $block_id, 'number' => ($block->number_prepend_zero) ? "0$number" : $number]) ?>
<?php $i = 0; foreach(range($block->first, $block->last) as $number): ?>
<?php $num = VoicenumberModel::getFirst(['voicenumberblock_id' => $block_id, 'number' => $number]) ?>
<tr>
<td><?=$block->countrycode?> <?=$block->areacode?> <?=($block->number_prepend_zero) ? "0" : ""?><?=$number?></td>
<td><?=$number?></td>
<td>
<?php if($num->active): ?>
<span class="text-success"><i class="fas fa-check"></i></span>

View File

@@ -474,6 +474,14 @@ class ContractController extends mfBaseController {
return $this->addAction();
}
// create journal
$journal = ContractjournalModel::create([
'contract_id' => $contract_id,
'type' => "created_from",
'value' => "manual"
]);
$journal->save();
$this->layout()->setFlash("Vertrag erfolgreich gespeichert.", "success");
/*
@@ -487,7 +495,22 @@ class ContractController extends mfBaseController {
'origin_contract_id' => $origin->id,
'type' => 'link'
]);
$link->save();
$link_id = $link->save();
if($link_id) {
$journal = ContractjournalModel::create([
'contract_id' => $contract_id,
'type' => "link",
'value' => $origin->id
]);
$journal->save();
$ojournal = ContractjournalModel::create([
'contract_id' => $origin->id,
'type' => "link",
'value' => $contract_id
]);
$ojournal->save();
}
}
}

View File

@@ -55,6 +55,12 @@ class ContractconfigController extends mfBaseController {
$this->redirect("Contract");
}
$contract = new Contract($contract_id);
if(!$contract->id) {
$this->layout()->setFlash("Contract ID nicht gefunden.","error");
$this->redirect("Contract");
}
if(!is_array($r->itemvalues) || !count($r->itemvalues)) {
$this->layout()->setFlash("Keine Änderungen.","info");
$this->redirect("Contract");
@@ -87,6 +93,9 @@ class ContractconfigController extends mfBaseController {
return $this->editAction();
}
// run custom productgroup hooks
$this->layout()->setFlash("Konfiguration gespeichert", "success");
$this->redirect("Contract", "view", ['id' => $contract_id]);

View File

@@ -0,0 +1,35 @@
<?php
abstract class Contractconfig_Hook {
protected $contract;
protected $items;
public function __construct(Contract $contract) {
if(method_exists($this, "init")) {
$this->init();
}
}
public function isResponsible() {
if(!$this->contract) return false;
// only work on contracts with our producttech attributes
if(!$this->testMyProductAttributes($contract)) {
return false;
}
}
private function testMyProductAttributes(Contract $contract) {
$product = $contract->product;
}
abstract public function beforeSave();
abstract public function afterSave();
abstract public function beforeDelete();
abstract public function afterDelete();
}

View File

@@ -0,0 +1,42 @@
<?php
class Contractconfig_Hook_Voip extends Contractconfig_Hook {
private $my_product_attributes = ["needs_number"];
/*
* Checks to determine if class needs to work on contract.
*/
public function isResponsible(Contract $contract) {
/*
* Test for standard checks
* (Only Producttech attributes for now)
*/
if(!parent::isResponsible()) {
return false;
}
// do additional checks
}
public function init() {
}
public function beforeSave() {
}
public function afterSave() {
}
public function beforeDelete() {
}
public function afterDelete() {
}
}

View File

@@ -30,6 +30,7 @@ class ContractconfigItemController extends mfBaseController {
}
$item_data['contractconfiggroup_id'] = $r->group_id;
$item_data['order'] = ($r->order && is_numeric($r->order)) ? $r->order : null;
$item_data['name'] = $r->name;
$item_data['displayname'] = $r->displayname;
$item_data['description'] = $r->description;

View File

@@ -0,0 +1,86 @@
<?php
class ContractjournalController extends mfBaseController {
protected function init() {
$this->needlogin=true;
$me = new User();
$me->loadMe();
$this->me = $me;
$this->layout()->set("me",$me);
if(!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
}
protected function saveAction() {
$r = $this->request;
//var_dump($r->get());exit;
$contract_id = $r->contract_id;
if(!is_numeric($contract_id) || $contract_id < 1) {
$this->layout()->setFlash("Contract nicht gefunden", "error");
$this->redirect("Contract");
}
$contract = new Contract($contract_id);
if(!$contract->id) {
$this->layout()->setFlash("Contract nicht gefunden", "error");
$this->redirect("Contract");
}
$journal_data = [];
$journal_data["contract_id"] = $contract_id;
$journal_data["text"] = ($r->text) ? $r->text : null;
$journal_data["type"] = "text";
if($r->type == "phone") $journal_data["type"] = "phone";
if($r->type == "file") $journal_data["type"] = "file";
if(in_array($r->type, ["text", "phone"])) {
if(!$journal_data['text']) {
$this->layout()->setFlash("Journaleintrag darf nicht leer sein", "error");
$this->redirect("Contract", "view", ['contract_id' => $contract_id]);
}
}
if($r->type == "file") {
try {
// returns File object or throws Exception on error
$file = mfUpload::handleFormUpload("journal_file");
} catch (Exception $ex) {
$this->layout()->setFlash("Fehler beim Dateiupload: ".$ex->getMessage(), "error");
$this->redirect("Contract", "view", ['contract_id' => $contract_id]);
}
$cf = ContractFileModel::create([
'contract_id' => $contract_id,
'file_id' => $file->id,
'name' => $file->name,
]);
$contractfile_id = $cf->save();
if(!$contractfile_id) {
$this->layout()->setFlash("Fehler beim Speichern der hochgeladenen Datei", "error");
$this->redirect("Contract", "view", ['contract_id' => $contract_id]);
}
$journal_data['type'] = "file";
$journal_data['value'] = $contractfile_id;
}
$journal = ContractjournalModel::create($journal_data);
$journal_id = $journal->save();
if(!$journal_id) {
$this->layout()->setFlash("Fehler beim Speichern des Journaleintrags", "error");
$this->redirect("Contract", "view", ['contract_id' => $contract_id]);
}
$this->layout()->setFlash("Journaleintrag erfolgreich gespeichert", "success");
$this->redirect("Contract", "view", ['contract_id' => $contract_id]);
}
}

View File

@@ -7,19 +7,12 @@ class Voicenumber extends mfBaseModel {
public function loadFromBlock(Voicenumberblock $block) {
$this->voicenumberblock_id = $block->id;
$this->countrycode = $block->countrycode;
$this->areacode = $block->areacode;
$this->number_prepend_zero = $block->number_prepend_zero;
//$this->countrycode = $block->countrycode;
//$this->areacode = $block->areacode;
//$this->number_prepend_zero = $block->number_prepend_zero;
return true;
}
public function getFullNumber() {
$number = $this->countrycode.$this->areacode.$this->number;
return $number;
}
public function beforeSave() {
if($this->ported_from && $this->port_in_date) {
$this->ported_in = 1;

View File

@@ -57,7 +57,7 @@ class VoicenumberController extends mfBaseController {
protected function saveAction() {
$r = $this->request;
//var_dump($r);
var_dump($r);exit;
$block_id = $r->block_id;
if(!is_numeric($block_id) || !$block_id) {
$this->layout()->setFlash("Rufnummer nicht gefunden1", "error");

View File

@@ -56,7 +56,7 @@ class VoicenumberModel {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
mfLoghandler::singleton()->debug($where);
//mfLoghandler::singleton()->debug($where);
$res = $db->select("Voicenumber", "*", "$where ORDER BY voicenumberblock_id, number");
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
@@ -146,21 +146,9 @@ class VoicenumberModel {
}
if(array_key_exists("number", $filter)) {
$add_zero = false;
$number = $filter['number'];
mfLoghandler::singleton()->debug($number);
if(substr($number,0, 1) === "0") {
$add_zero = true;
$number = substr($number, 1);
}
if(is_numeric($number)) {
$where .= " AND number = $number";
if($add_zero) {
$where .= " AND number_prepend_zero = 1";
}
}
}

View File

@@ -5,42 +5,12 @@ class Voicenumberblock extends mfBaseModel {
private $number_first;
private $number_last;
private $base;
private $short_prefix;
private $short_first;
private $short_last;
private $files;
private $numbers;
private function getFullNumber($last = false) {
if($last) {
$number = $this->countrycode.$this->areacode.$this->getLast();
} else {
$number = $this->countrycode.$this->areacode.$this->getFirst();
}
return $number;
}
public function getFirst() {
if($this->number_prepend_zero) {
return "0".$this->first;
}
return $this->first;
}
public function getLast() {
if($this->number_prepend_zero) {
return "0".$this->last;
}
return $this->last;
}
public function getBaseNumber() {
$base = floor($this->first / pow(10, ceil(log10($this->last - $this->first))));
if($this->number_prepend_zero) {
return "0".$base;
}
return $base;
}
public function isNumberInBlock($number) {
return ($number >= $this->first && $number <= $this->last);
}
@@ -58,16 +28,17 @@ class Voicenumberblock extends mfBaseModel {
return $this->numbers;
}
if($name == "number_first") {
return $this->getFullNumber();
if($name == "short_prefix") {
$this->short_prefix = substr($this->prefix, strlen($this->countrycode.$this->areacode));
return $this->short_prefix;
}
if($name == "number_last") {
return $this->getFullNumber(true);
if($name == "short_first") {
$this->short_first = substr($this->first, strlen($this->countrycode.$this->areacode));
return $this->short_first;
}
if($name == "base") {
return $this->getBaseNumber();
if($name == "short_last") {
$this->short_last = substr($this->last, strlen($this->countrycode.$this->areacode));
return $this->short_last;
}
$classname = ucfirst($name);

View File

@@ -4,9 +4,9 @@ class VoicenumberblockModel {
public $name;
public $countrycode;
public $areacode;
public $prefix;
public $first;
public $last;
public $number_prepend_zero;
public $comment;
public $create_by;
@@ -138,56 +138,24 @@ class VoicenumberblockModel {
}
if(array_key_exists("first", $filter)) {
$add_zero = false;
$first = $filter['first'];
mfLoghandler::singleton()->debug($first);
if(substr($first,0, 1) === "0") {
$add_zero = true;
$first = substr($first, 1);
}
if(is_numeric($first)) {
$where .= " AND first like '%$first%'";
if($add_zero) {
$where .= " AND number_prepend_zero = 1";
}
$where .= " AND first = '$first'";
}
}
if(array_key_exists("last", $filter)) {
$add_zero = false;
$last = $filter['last'];
mfLoghandler::singleton()->debug($last);
if(substr($last,0, 1) === "0") {
$add_zero = true;
$last = substr($last, 1);
}
if(is_numeric($last)) {
$where .= " AND last like '%$last%'";
$where .= " AND last = '$last'";
}
}
if(array_key_exists("number", $filter)) {
$add_zero = false;
$number = $filter['number'];
mfLoghandler::singleton()->debug($number);
if(substr($number,0, 1) === "0") {
$add_zero = true;
$number = substr($number, 1);
}
if(is_numeric($number)) {
$where .= " AND first <= $number AND last >= $number";
if($add_zero) {
$where .= " AND number_prepend_zero = 1";
}
}
}

View File

@@ -46,6 +46,58 @@ class mfUpload {
}
}
static public function handleFormUpload($uplName, $filename = false, $subfolder = false, $savepath = MFUPLOAD_FILE_SAVE_PATH) {
if(!isset($_FILES) || !array_key_exists($uplName, $_FILES)) {
throw new Exception("Uploaded file not found");
}
if($_FILES['OrderFileUpload']['error']) {
throw new Exception("Error receiving file");
}
$upload_error = false;
$savepath = preg_replace('#/+$#', "", $savepath); // remove trailing slash
if($subfolder) {
$subfolder = preg_replace('#^/+#', "", $subfolder); // remove leading slash
$subfolder = preg_replace('#/+$#', "", $subfolder); // remove trailing slash
$savepath .= "/$subfolder";
}
$upload = new mfUpload($uplName);
$upload->setSavepath($savepath);
if(!$upload->getSize()) {
throw new Exception("Datei darf nicht leer sein");
}
if(substr(strtolower($upload->getFilename()), -3, 3) == "pdf" && !$upload->validatePDF()) {
throw new Exception("PDF-Validierung fehlgeschlagen");
}
try {
$upload->save();
} catch (Exception $ex) {
throw $ex;
}
$file_data = [];
$file_data['name'] = ($filename) ? $filename : $upload->getOriginalFilename();
$file_data['filename'] = ($filename) ? $filename : $upload->getOriginalFilename();
$file_data['subfolder'] = $subfolder;
$file_data['store_filename'] = $upload->getFilename();
$file_data['orig_filename'] = $upload->getOriginalFilename();
$file = FileModel::create($file_data);
$file_id = $file->save();
if(!$file_id) {
unlink($upload->getSavepath()."/".$upload->getFilename());
throw new Exception("Datei konnte nicht angelegt werden");
}
return $file;
}
public function getSavepath() {
return $this->savepath;
}

View File

@@ -83,6 +83,9 @@ h1, h2, h3, h4, h5, h6 {
.card.border-top-warning {
border-top: 2px solid #f7b84b;
}
.card.border-top-info {
border-top: 2px solid #4b88e4;
}
/*
.card-header.underline-danger {
border-bottom: 2px solid #f1556c;