Merge branch 'fronkdev' into 'master'

Added fullscreen mode to maps

See merge request fronk/thetool!514
This commit is contained in:
Frank Schubert
2024-07-25 12:27:53 +00:00
20 changed files with 999 additions and 292 deletions

View File

@@ -397,7 +397,7 @@
});
}
} else {
buildingMap = L.map('building-map').setView([<?=TT_PLACEHOLDER_GPS_LAT?>, <?=TT_PLACEHOLDER_GPS_LONG?>], 12);
buildingMap = L.map('building-map', {fullscreenControl: true}).setView([<?=TT_PLACEHOLDER_GPS_LAT?>, <?=TT_PLACEHOLDER_GPS_LONG?>], 12);
}
if(!(currentTileset in tileLayers)) {

View File

@@ -1,3 +1,7 @@
<?php
$f = false;
$hide_credit = false;
?>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); ?>
<!-- start page title -->
@@ -12,7 +16,7 @@
<li class="breadcrumb-item"><a
href="<?=self::getUrl("Contract", "view", ['id' => $contract->id])?>"><?=$contract->product_name?>
[<?=$contract->matchcode?>]</a></li>
<li class="breadcrumb-item active">Product-/Standortwechsel</li>
<li class="breadcrumb-item active">Produkt-/Standortwechsel</li>
</ol>
</div>
<h4 class="page-title">Aktives Produkt</h4>
@@ -31,7 +35,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>
@@ -77,246 +81,7 @@
</div>
<div class="card">
<div class="card-body">
<h4 class="text-center mb-3">Neuer Contract</h4>
<form method="post" action="<?=self::getUrl("Contract", "saveProductchange")?>">
<input type="hidden" name="contract_id" value="<?=$contract->id?>"/>
<div class="row justify-content-center">
<div class="col-xl-10">
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_id">Produkt</label>
<div class="col-lg-10">
<select class="form-control basicAutoComplete" autocomplete="off"
name="product_id" id="product_id"
data-url="<?=self::getUrl('Product', 'api')?>?do=findProduct&autocomplete=1"
placeholder="Tippen zum suchen..."
data-noresults-text="Keine Suchergebnisse">
<option></option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="matchcode">Matchcode:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="matchcode" id="matchcode"
value="<?=$contract->matchcode?>">
<small class="font-italic">Eindeutige Identifizierung das Produkts. Z.B.
Anschlussadresse, Domainname usw.</small>
</div>
</div>
<?php if(
(is_array($contract->product->attributes) && count($contract->product->attributes))
&& (array_key_exists(TT_ATTRIB_TERMINATION_REQUIRED_NAME, $contract->product->attributes)
&& $contract->product->attributes[TT_ATTRIB_TERMINATION_REQUIRED_NAME]->value == 1)
|| $contract->termination_id
): ?>
<div class="form-group row" id="termination_id-line">
<?php else: ?>
<div class="form-group row hidden" id="termination_id-line">
<?php endif; ?>
<label class="col-lg-2 col-form-label" for="matchcode">Anschluss</label>
<div class="col-lg-10">
<select name="termination_id" id="termination_id"
class="form-control select2">
<option></option>
<?php foreach($terminations as $t): ?>
<option value="<?=$t->id?>" <?=($t->id == $contract->termination_id) ? "selected='selected'" : ""?>><?=$t->code?>
- <?=$t->getAddress(true)?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_name">Individueller
Produktname:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="product_name"
id="product_name" value="<?=$contract->product_name?>">
<small class="font-italic">Scheint statt dem echten Produktnamen auf der
Rechnung auf</small>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_info">Produkt
Zusatztext:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="product_info"
id="product_info" value="<?=$contract->product_info?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price_setup">Preis Setup:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_setup" id="price_setup"
value="<?=$contract->price_setup?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price">Preis Periodisch:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price" id="price"
value="<?=$contract->price?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price_nne">Preis NNE</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_nne" id="price_nne"
value="<?=$contract->price_nne?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price_nbe">Preis NBE</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_nbe" id="price_nbe"
value="<?=$contract->price_nbe?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label"
for="billing_period">Verrechnungsperiode</label>
<div class="col-lg-10">
<select class="form-control" name="billing_period" id="billing_period"
placeholder="Verrechnungsperiode">
<option value="1" <?=($product->billing_period == 1) ? "selected='selected'" : ""?>>
Monatlich
</option>
<option value="12" <?=($product->billing_period == 12) ? "selected='selected'" : ""?>>
Jährlich
</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="billing_delay">Verzögerter
Verrechnungsstart</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="billing_delay"
id="billing_delay" placeholder="Freimonate"
value="<?=$contract->billing_delay?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="billing_delay">Fertigstellungsdatum</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="finish_date" id="finish_date" value="">
</div>
</div>
<?php if((is_array($contract->linkFrom) && count($contract->linkFrom)) || (is_array($contract->linkTo) && count($contract->linkTo))): ?>
<h4>Verknüpfte Verträge</h4>
<table class="table table-striped table-sm table-bordered table-hover"
id="link-table">
<tr>
<th title="Verlinkten Contract mit neuem Contract verknüpfen">
Übernehmen
</th>
<th title="Verlinkten Contract mit altem Contract zusammen kündigen">
Kündigen
</th>
<th>Kü.Datum</th>
<th>Kunde</th>
<th>Contract ID</th>
<th>Produkt</th>
<th>Matchcode</th>
<th>Bestelldatum</th>
<th>Fertigstellung</th>
<th>Kündigung</th>
</tr>
<?php foreach($contract->linksWithCredit as $link): ?>
<?php
if($link->contract_id == $contract->id) {
$linkcontract = $link->origin;
} else {
$linkcontract = $link->contract;
}
if($linkcontract->isCancelled()) continue;
?>
<tr data-link-type="<?=$link->type?>">
<td>
<input type="radio" class="form-check link-keep"
id="link-<?=$link->id?>-action-keep"
name="links[<?=$link->id?>][action]"
value="keep" <?=($linkcontract->cancel_date && $linkcontract->cancel_date < date('U')) ? "" : "checked='checked'"?>
onchange="linkActionChange(<?=$link->id?>)" />
<?php if($link->type == "credit"): ?>
(Gutschrift wird neu erstellt)
<?php endif; ?>
</td>
<td>
<input type="radio" class="form-check link-cancel"
id="link-<?=$link->id?>-action-cancel"
name="links[<?=$link->id?>][action]" value="cancel"
onchange="linkActionChange(<?=$link->id?>)" />
</td>
<td>
<input type="text" class="form-control hidden" id="link-<?=$link->id?>-cancel_date" name="links[<?=$link->id?>][cancel_date]" value="<?=$linkcontract->getRegularCanceldate()?>" />
</td>
<td>
<a href="<?=self::getUrl("Address", "View", ["id" => $linkcontract->owner_id])?>" target="_blank"><?=$linkcontract->owner->getCompanyOrName()?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->id?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->product_name?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->matchcode?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->order_date) ? date('d.m.Y', $linkcontract->order_date) : ""?></td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->finish_date) ? date('d.m.Y', $linkcontract->finish_date) : ""?></td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->cancel_date) ? date('d.m.Y', $linkcontract->cancel_date) : ""?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<!-- TODO: Fileupload -->
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="note">Interne Notiz</label>
<div class="col-lg-10">
<textarea id="note" class="form-control" name="note"
rows="5"><?=$contract->note?></textarea>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col text-center">
<input type="submit" class="btn btn-primary" value="Produktwechsel speichern"/>
</div>
</div>
</form>
</div>
</div>
<?php include(realpath(dirname(__FILE__))."/include/productchange-action.php"); ?>
<div class="card">
@@ -435,7 +200,7 @@
function linkActionChange(link_id) {
//console.log($("#link-" + link_id + "-action-cancel").prop("checked"));
if($("#link-" + link_id + "-action-cancel").prop("checked")) {
if($("#link-" + link_id + "-action-cancel").prop("checked") && $("#finish_date").val()) {
$("#link-" + link_id + "-cancel_date").show();
} else {
$("#link-" + link_id + "-cancel_date").hide();

View File

@@ -231,7 +231,7 @@
<button type="button" class="btn btn-sm btn-outline-secondary"><i class="far fa-people-arrows fa-fw"></i> Inhaberwechsel</button>
<a href="<?=self::getUrl("Contract", "productchange", ["contract_id" => $contract->id])?>"><button type="button" class="btn btn-sm btn-outline-purple"><i class="far fa-truck-container fa-fw"></i> Produkt-/Standortwechsel</button></a>
<a href="<?=self::getUrl("Contract", "cancel", ["contract_id" => $contract->id])?>"><button type="button" class="btn btn-sm btn-outline-danger"><i class="far fa-axe fa-fw"></i> Kündigen</button></a>
<?php else: ?>
<?php elseif(!$contract->finish_date): ?>
<a href="<?=self::getUrl("Contract", "finishContract", ['contract_id' => $contract->id])?>" onclick="if(!confirm('Jetzt fertigstellen und in Verrechnung geben?')) return false"><button type="button" class="btn btn-sm btn-success"><i class="far fa-face-confused fa-fw"></i> Jetzt fertigstellen</button></a>
<?php endif; ?>
</td>

View File

@@ -0,0 +1,359 @@
<div class="card border-top-purple">
<div class="card-body">
<h4 class="text-center mb-3">Neuer Contract</h4>
<form method="post" action="<?=self::getUrl("Contract", "saveProductchange")?>">
<input type="hidden" name="contract_id" value="<?=$contract->id?>"/>
<?php if($f): ?>
<input type="hidden" name="f" value="<?=$f?>" />
<?php endif; ?>
<div class="row justify-content-center">
<div class="col-xl-10">
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_id">Produkt *</label>
<div class="col-lg-10">
<select class="form-control basicAutoComplete" autocomplete="off"
name="product_id" id="product_id"
data-url="<?=self::getUrl('Product', 'api')?>?do=findProduct&autocomplete=1"
placeholder="Tippen zum suchen..."
data-noresults-text="Keine Suchergebnisse">
<option></option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="matchcode">Matchcode:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="matchcode" id="matchcode"
value="<?=$contract->matchcode?>">
<small class="font-italic">Eindeutige Identifizierung das Produkts. Z.B.
Anschlussadresse, Domainname usw.</small>
</div>
</div>
<?php if(
(is_array($contract->product->attributes) && count($contract->product->attributes))
&& (array_key_exists(TT_ATTRIB_TERMINATION_REQUIRED_NAME, $contract->product->attributes)
&& $contract->product->attributes[TT_ATTRIB_TERMINATION_REQUIRED_NAME]->value == 1)
|| $contract->termination_id
): ?>
<div class="form-group row" id="termination_id-line">
<?php else: ?>
<div class="form-group row hidden" id="termination_id-line">
<?php endif; ?>
<label class="col-lg-2 col-form-label" for="matchcode">Anschluss *</label>
<div class="col-lg-10">
<select name="termination_id" id="termination_id"
class="form-control select2">
<option></option>
<?php foreach($terminations as $t): ?>
<option value="<?=$t->id?>" <?=($t->id == $contract->termination_id) ? "selected='selected'" : ""?>><?=$t->code?>
- <?=$t->getAddress(true)?></option>
<?php endforeach; ?>
</select>
<small>Anschluss nicht gefunden? <a href="<?=self::getUrl("Building")?>" target="_blank">Bitte anlegen</a></small>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_name">Individueller
Produktname:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="product_name"
id="product_name" value="<?=$contract->product_name?>">
<small class="font-italic">Scheint statt dem echten Produktnamen auf der
Rechnung auf</small>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="product_info">Produkt
Zusatztext:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="product_info"
id="product_info" value="<?=$contract->product_info?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price_setup">Preis Setup:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_setup" id="price_setup"
value="<?=$contract->price_setup?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="price">Preis Periodisch:</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price" id="price"
value="<?=$contract->price?>">
</div>
</div>
<div class="form-group row <?=$me->isAdmin() ? "" : "hidden"?>">
<label class="col-lg-2 col-form-label" for="price_nne">Preis NNE</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_nne" id="price_nne"
value="<?=$contract->price_nne?>">
</div>
</div>
<div class="form-group row <?=$me->isAdmin() ? "" : "hidden"?>">
<label class="col-lg-2 col-form-label" for="price_nbe">Preis NBE</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="price_nbe" id="price_nbe"
value="<?=$contract->price_nbe?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label"
for="billing_period">Verrechnungsperiode *</label>
<div class="col-lg-10">
<select class="form-control" name="billing_period" id="billing_period"
placeholder="Verrechnungsperiode">
<option value="1" <?=($product->billing_period == 1) ? "selected='selected'" : ""?>>
Monatlich
</option>
<option value="12" <?=($product->billing_period == 12) ? "selected='selected'" : ""?>>
Jährlich
</option>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="billing_delay">Verzögerter
Verrechnungsstart</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="billing_delay"
id="billing_delay" placeholder="Freimonate"
value="<?=$contract->billing_delay?>">
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="billing_delay">Fertigstellungsdatum</label>
<div class="col-lg-10">
<input type="text" class="form-control" name="finish_date" id="finish_date" value="" />
</div>
</div>
<?php if((is_array($contract->linkFrom) && count($contract->linkFrom)) || (is_array($contract->linkTo) && count($contract->linkTo))): ?>
<h4 class="mt-4">Verknüpfte Verträge</h4>
<table class="table table-striped table-sm table-bordered table-hover"
id="link-table">
<tr>
<th title="Verlinkten Contract mit neuem Contract verknüpfen">
Übernehmen
</th>
<th title="Verlinkten Contract mit altem Contract zusammen kündigen">
Kündigen
</th>
<th>Kü.Datum</th>
<th>Kunde</th>
<th>Contract ID</th>
<th>Produkt</th>
<th>Matchcode</th>
<th>Bestelldatum</th>
<th>Fertigstellung</th>
<th>Kündigung</th>
</tr>
<?php foreach($contract->linksWithCredit as $link): ?>
<?php
if($link->contract_id == $contract->id) {
$linkcontract = $link->origin;
} else {
$linkcontract = $link->contract;
}
if($linkcontract->isCancelled()) continue;
?>
<tr data-link-type="<?=$link->type?>" class="<?=($hide_credit && $link->type == "credit") ? "hidden" : ""?>">
<td>
<input type="radio" class="form-check link-keep"
id="link-<?=$link->id?>-action-keep"
name="links[<?=$link->id?>][action]"
value="keep" <?=($linkcontract->cancel_date && $linkcontract->cancel_date < date('U')) ? "" : "checked='checked'"?>
onchange="linkActionChange(<?=$link->id?>)" />
<?php if($link->type == "credit"): ?>
(Gutschrift wird neu erstellt)
<?php endif; ?>
</td>
<td>
<input type="radio" class="form-check link-cancel"
id="link-<?=$link->id?>-action-cancel"
name="links[<?=$link->id?>][action]" value="cancel"
onchange="linkActionChange(<?=$link->id?>)" />
</td>
<td>
<input type="text" class="form-control hidden" id="link-<?=$link->id?>-cancel_date" name="links[<?=$link->id?>][cancel_date]" value="<?=$linkcontract->getRegularCanceldate()?>" />
</td>
<td>
<a href="<?=self::getUrl("Address", "View", ["id" => $linkcontract->owner_id])?>" target="_blank"><?=$linkcontract->owner->getCompanyOrName()?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->id?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->product_name?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>">
<a href="<?=self::getUrl("Contract", "View", ["contract_id" => $linkcontract->id])?>" target="_blank"><?=$linkcontract->matchcode?></a>
</td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->order_date) ? date('d.m.Y', $linkcontract->order_date) : ""?></td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->finish_date) ? date('d.m.Y', $linkcontract->finish_date) : ""?></td>
<td class="contract <?=($linkcontract->isCancelled()) ? "canceled" : ""?>"><?=($linkcontract->cancel_date) ? date('d.m.Y', $linkcontract->cancel_date) : ""?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif; ?>
<!-- TODO: Fileupload -->
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="note">Interne Notiz</label>
<div class="col-lg-10">
<textarea id="note" class="form-control" name="note"
rows="5"><?=$contract->note?></textarea>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col text-center">
<input type="submit" class="btn btn-purple" value="Produktwechsel speichern"/>
</div>
</div>
</form>
</div>
</div>
<script>
$(".select2").select2({
allowClear: true,
placeholder: ""
});
$("#finish_date").datepicker({
language: 'de',
format: "dd.mm.yyyy",
showWeekDays: true,
todayBtn: 'linked',
autoclose: true
});
/*
* product autocomplete
*/
<?php if($contract->product_id && is_object(($contract->product))): ?>
$('#product_id').autoComplete('set', {
value: <?=$contract->product_id?>,
text: '<?=($contract->product_id) ? str_replace("'", "\\'", str_replace(["\n", "\r"], " ", $contract->product->name)) . " [" . $contract->product_id . "]" : ""?>'
});
<?php else: ?>
$('#product_id').autoComplete();
<?php endif; ?>
$('#product_id').keydown(function () {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
});
$('#product_id').on("autocomplete.select", function (evt, item) {
if (item && item.value === 0) {
$('#product_id').autoComplete('set', null);
}
if (item && item.value) {
updateProduct(item.value);
}
});
// product autocomplete
function updateProduct() {
var pid = $('input[name=product_id]').val();
$.get("<?=self::getUrl("Product", "Api")?>",
{
"do": "getProduct",
product_id: pid
},
function (success) {
//console.log(success);
p = success.result.product;
$('#product_name').val(p.name);
//$('#product_info').val(p.name);
$('#billing_delay').val(p.billing_delay);
$('#billing_period').val(p.billing_period);
$('#price').val(p.price);
$('#price_setup').val(p.price_setup);
$('#price_nne').val(p.price_nne);
$('#price_nbe').val(p.price_nbe);
if (typeof p.attributes === 'object' && "termination_required" in p.attributes && p.attributes.termination_required == 1) {
$('#termination_id-line').show();
$('#termination_id').select2({
allowClear: true,
placeholder: ""
});
} else {
$('#termination_id-line').hide();
//$('#termination_id-' + id + '-line').hide();
}
// set credit-link to cancel if new product does not need credit
const attrib = p.attributes;
let crediting_partner = false;
let crediting_rate = 0;
if (crediting_partner in p.attributes) {
crediting_partner = parseInt(p.attributes.crediting_partner);
}
if (crediting_rate in p.attributes) {
crediting_rate = parseFloat(p.attributes.crediting_rate);
}
let price_nne = parseFloat(p.price_nne);
//console.log(p.price_nne, crediting_partner, crediting_rate);
if (price_nne || (crediting_partner && crediting_rate)) {
$("#link-table tr[data-link-type='credit'] input.link-keep").prop("checked", "checked");
}
if (!price_nne && (!crediting_partner || !crediting_rate)) {
$("#link-table tr[data-link-type='credit'] input.link-cancel").prop("checked", "checked");
}
},
'json');
}
function linkActionChange(link_id) {
//console.log($("#link-" + link_id + "-action-cancel").prop("checked"));
if($("#link-" + link_id + "-action-cancel").prop("checked") && $("#finish_date").val()) {
$("#link-" + link_id + "-cancel_date").show();
} else {
$("#link-" + link_id + "-cancel_date").hide();
}
//link-<?=$link->id?>-action-cancel
}
</script>

View File

@@ -142,7 +142,8 @@
<div class="row">
<div class="col-12">
<div class="float-right">
<a class="btn btn-lg btn-primary mb-2" href="<?=self::getUrl("Order", "add")?>"><i class="fas fa-square-plus mr-1"></i> Neue Bestellung anlegen</a>
<a class="btn btn-lg btn-primary mb-2" href="<?=self::getUrl("Order", "add")?>"><i class="fas fa-fw fa-square-plus "></i> Neue Bestellung anlegen</a>
<!--a class="btn btn-lg btn-purple mb-2 ml-2" href="<?=self::getUrl("Order", "addUpgrade")?>"><i class="fas fa-fw fa-square-up "></i> Upgrade eingeben</a-->
</div>
</div>
</div>

View File

@@ -0,0 +1,98 @@
<?php
$urlfilter = [];
if($s) {
$urlfilter['s'] = $s;
}
if($noTermProducts) {
$urlfilter['noTermProducts'] = 1;
}
if(isset($filter) && is_array($filter) && count($filter)) {
$urlfilter["filter"] = $filter;
}
$posturl = self::getUrl("Order", "save", $urlfilter);
?>
<?php include(realpath(dirname(__FILE__)."/../../$mfLayoutPackage")."/header.php"); ?>
<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box">
<div class="page-title-right">
<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("Order")?>">Bestellungen</a></li>
<li class="breadcrumb-item active">Produktwechsel</li>
</ol>
</div>
<h4 class="page-title">Bestellungen</h4>
</div>
</div>
</div>
<!-- end page title -->
<div class="row">
<div class="col-lg-12">
<div class="card no-shadow">
<div class="card-body bg-light">
<h4 class="mb-2">Produktwechsel</h4>
<form class="form-horizontal" method="post" action="<?=$posturl?>" name="orderForm" id="orderForm" enctype="multipart/form-data">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-lg-6" id="owner-block">
<div class="form-group row">
<div class="col-lg-12 mb-2">
<h4>Vertragsinhaber auswählen</h4>
<select class="form-control basicAutoComplete" autocomplete="off" name="owner_id" id="owner_id" data-url="<?=self::getUrl('Address','api')?>?do=findAddress&autocomplete=1" placeholder="Tippen zum Suchen... (Bestandskunden)" data-noresults-text="Keine Suchergebnisse">
<option></option>
</select>
</div>
<div class="card" id="product-list">
<div class="card-body">
<table>
<thead>
<th>Contract ID</th>
<th>Produkt</th>
<th>Matchcode</th>
<th>Preis p.P.</th>
<th>Herstellungskosten</th>
<th>Fertigstellung</th>
<th>Kündigung</th>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
</script>
<?php include(realpath(dirname(__FILE__)."/../../$mfLayoutPackage")."/footer.php"); ?>

View File

@@ -0,0 +1,95 @@
<?php
$f = "o";
$hide_credit = true;
?>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); ?>
<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box">
<div class="page-title-right">
<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("Order")?>">Bestellungen</a></li>
<li class="breadcrumb-item active">Produkt-/Standortwechsel</li>
</ol>
</div>
<h4 class="page-title">Aktives Produkt</h4>
</div>
</div>
</div>
<!-- end page title -->
<div class="row">
<div class="col-lg-12">
<div class="card">
<div class="card-body">
<a href="<?=self::getUrl("Order")?>" class="btn btn-sm btn-secondary mr-1"><i class="fas fa-list"></i> Zurück zu Bestellungen</a>
</div>
</div>
<div class="card border-top-success">
<div class="card-body">
<h3 class="text-center mb-3"><?=$contract->product_name?> (<?=$contract->id?>)</h3>
<table class="table table-sm table-striped view-table">
<tr>
<th style="max-width: 50vw;">Matchcode:</th>
<td style="width: 50vw;"><?=$contract->matchcode?></td>
</tr><tr>
<th>Vertragsinhaber:</th>
<td>
<a href="<?=self::getUrl("Address", "View", ["id" => $contract->owner->id])?>"><?=$contract->owner->getCompanyOrName()?>
(<?=$contract->owner->customer_number?>)
</a>
</td>
</tr><tr>
<th>Produkt:</th>
<td><?=$contract->product_name?> [<?=$contract->product_id?>
]<?=($contract->product_name != $contract->product->name) ? " <i>(" . $contract->product->name . ")</i>" : ""?></td>
</tr><tr>
<th>Produkt Info:</th>
<td><?=$contract->product_info?></td>
</tr><tr>
<th>Preis Netto:</th>
<td class="<?=($contract->price < 0) ? "text-danger" : ""?>">€ <?=number_format(($contract->amount != 1) ? $contract->price * $contract->amount : $contract->price, 4, ",", ".")?></td>
</tr><tr>
<th>Preis Brutto:</th>
<td class="<?=($contract->price < 0) ? "text-danger" : ""?>">€
<?php if($contract->price && $contract->vatrate): ?>
<?php if($contract->amount != 1): ?>
<?=number_format($contract->price + ($contract->price / 100) * $contract->vatrate, 4, ",", ".")?>
<?php else: ?>
<?=number_format(($contract->price + ($contract->price / 100) * $contract->vatrate) * $contract->amount, 4, ",", ".")?>
<?php endif; ?>
<?php endif; ?>
</td>
</tr><tr>
<th>Fertigstellungsdatum:</th>
<td><?=date("d.m.Y", $contract->finish_date)?></td>
</tr>
</table>
</div>
</div>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage")."/Contract/include/productchange-action.php"); ?>
<div class="card">
<div class="card-body">
<a href="<?=self::getUrl("Order")?>" class="btn btn-sm btn-secondary mr-1"><i class="fas fa-list"></i> Zurück zu Bestellungen</a>
</div>
</div>
</div>
</div>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -437,7 +437,7 @@
});
}
} else {
preorderMap = L.map('preorder-map').setView([<?=TT_PLACEHOLDER_GPS_LAT?>, <?=TT_PLACEHOLDER_GPS_LONG?>], 12);
preorderMap = L.map('preorder-map', {fullscreenControl: true}).setView([<?=TT_PLACEHOLDER_GPS_LAT?>, <?=TT_PLACEHOLDER_GPS_LONG?>], 12);
}
if(!(currentTileset in tileLayers)) {

View File

@@ -19,6 +19,7 @@
<link href="<?=self::getResourcePath()?>assets/css/icons.css" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/css/app.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/css/leaflet.css" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/css/leaflet.fullscreen.css" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/css/thetool.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/libs/select2/select2.min.css" rel="stylesheet" type="text/css" />
<link href="<?=self::getResourcePath()?>assets/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
@@ -39,6 +40,7 @@
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.de.min.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/geo/geo.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/Leaflet.fullscreen.min.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.MakiMarkers.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>js/popper.min.js"></script>
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap.min.js"></script>

View File

@@ -346,6 +346,8 @@ class BillingController extends mfBaseController {
$total_days = $last_of_period->diff($first_of_period)->format("%a") + 1;
$period_days = ($end_date->diff($start_date)->format("%a")) + 1;
if($period_days < 0) continue; // don't bill for negative time range
$pc = $period_days / $total_days * 100;
$price = round($contract->price / 100 * $pc, 4);

View File

@@ -11,7 +11,7 @@ class ContractController extends mfBaseController
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
if (!$me->is(["Admin", "salespartner", "netowner"])) {
$this->redirect("Dashboard");
}
}
@@ -19,6 +19,10 @@ class ContractController extends mfBaseController
protected function indexAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$this->layout()->setTemplate("Contract/Index");
if ($this->request->resetFilter) {
@@ -87,6 +91,10 @@ class ContractController extends mfBaseController
protected function viewAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$this->layout()->setTemplate("Contract/View");
$id = $this->request->contract_id;
@@ -116,6 +124,9 @@ class ContractController extends mfBaseController
}
protected function cancelAction() {
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$this->layout()->setTemplate("Contract/CancelForm");
$id = $this->request->contract_id;
@@ -154,6 +165,9 @@ class ContractController extends mfBaseController
}
protected function saveCancel() {
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$r = $this->request;
$id = $r->contract_id;
@@ -212,6 +226,9 @@ class ContractController extends mfBaseController
}
protected function sendCancelNotification() {
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$contract_id = $this->request->contract_id;
$contract = new Contract($contract_id);
@@ -238,23 +255,65 @@ class ContractController extends mfBaseController
{
$this->layout()->setTemplate("Contract/ProductchangeForm");
$f = $this->request->f;
if(!$f) {
$f = "c"; // from Contract
}
$this->layout()->set("f", $f);
$id = $this->request->contract_id;
if (!$id) {
$id = $this->request->id;
}
if (!is_numeric($id) || !$id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Contract");
if($f == "o") {
$this->redirect("Order", "addUpgrade");
} else {
$this->redirect("Contract");
}
}
$contract = new Contract($id);
if (!$contract->id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Contract");
if($f == "o") {
$this->redirect("Order", "addUpgrade");
} else {
$this->redirect("Contract");
}
}
if($this->me->isAdmin()) {
$this->layout()->set("terminations", TerminationModel::getAll());
} else {
// check permissions
// check if correct network
$my_network_ids = [];
foreach($this->me->my_networks as $network) {
$my_network_ids[] = $network->id;
}
if($contract->termination_id) {
if(!in_array($contract->termination->network_id, $my_network_ids)) {
if($f == "o") {
// from Order, redirect back to Order
$this->layout()->setFlash("Keine Berechtigung", "error");
$this->redirect("Order", "addUpgrade", ["owner_id" => $contract->owner_id]);
}
}
}
$terms = TerminationModel::search(["network_id" => $my_network_ids]);
$this->layout()->set("terminations", $terms);
}
$this->layout()->set("contract", $contract);
$this->layout()->set("terminations", TerminationModel::getAll());
if ($this->request->filter) {
$this->layout()->set("filter", $this->request->filter);
@@ -266,19 +325,36 @@ class ContractController extends mfBaseController
protected function saveProductchangeAction()
{
if(!$this->me->is(["Admin", "salespartner", "netowner"])) {
$this->redirect("Dashboard");
}
$r = $this->request;
//var_dump($r->links);exit;
$f = $r->f;
if(!$f) {
$f = "c"; // from Contract
}
$id = $r->contract_id;
if (!is_numeric($id) || !$id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Contract");
if($f == "o") {
$this->redirect("Order", "addUpgrade");
} else {
$this->redirect("Contract");
}
}
$contract = new Contract($id);
if (!$contract->id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Contract");
if($f == "o") {
$this->redirect("Order", "addUpgrade");
} else {
$this->redirect("Contract");
}
}
$new_contract = clone($contract);
@@ -303,7 +379,12 @@ class ContractController extends mfBaseController
$product = new Product($r->product_id);
if (!$product->id) {
$this->layout()->setFlash("Produkt nicht gefunden", "error");
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
if($f == "o") {
$this->redirect("Contract", "productchange", ["contract_id" => $id, "f" => $f]);
} else {
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
}
}
$contract_data['product_external'] = $product->external;
@@ -315,7 +396,11 @@ class ContractController extends mfBaseController
$finish_date = DateTime::createFromFormat("d.m.Y", $r->finish_date, new DateTimeZone("Europe/Vienna"));
} catch (Exception $e) {
$this->layout()->setFlash("Ungültiges Kündigungsdateum", "error");
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
if($f == "o") {
$this->redirect("Contract", "productchange", ["contract_id" => $id, "f" => $f]);
} else {
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
}
}
$finish_date->setTime(0,0,0);
@@ -334,7 +419,11 @@ class ContractController extends mfBaseController
if (!$contract_data['termination_id'] || !$termination->id) {
$this->layout()->setFlash("Produkt erfordert Anschluss.", "error");
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
if($f == "o") {
$this->redirect("Contract", "productchange", ["contract_id" => $id, "f" => $f]);
} else {
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
}
}
} else {
$contract_data['termination_id'] = null;
@@ -371,7 +460,11 @@ class ContractController extends mfBaseController
$cancel_date = DateTime::createFromFormat("d.m.Y", $link_data["cancel_date"], new DateTimeZone("Europe/Vienna"));
} catch (Exception $e) {
$this->layout()->setFlash("Ungültiges Kündigungsdateum", "error");
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
if($f == "o") {
$this->redirect("Contract", "productchange", ["contract_id" => $id, "f" => $f]);
} else {
$this->redirect("Contract", "productchange", ["contract_id" => $id]);
}
}
}
@@ -408,7 +501,7 @@ class ContractController extends mfBaseController
}
if ($action == "cancel") {
if($cancel_date) {
if($cancel_date && $contract_cancel_date) {
// insert cancel_date in old contract
$lc = new Contract($origin_id);
$lc->cancel_date = $cancel_date->getTimestamp();
@@ -497,13 +590,21 @@ class ContractController extends mfBaseController
}
$this->layout()->setFlash("Neuer Contract erfolgreich erstellt", "success");
$this->redirect("Contract", "view", ["contract_id" => $new_contract_id]);
if($f == "o") {
$this->redirect("Order");
} else {
$this->redirect("Contract", "view", ["contract_id" => $new_contract_id]);
}
}
protected function finishContractAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$r = $this->request;
$id = $r->contract_id;
@@ -550,6 +651,9 @@ class ContractController extends mfBaseController
protected function addAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$this->layout()->setTemplate("Contract/Form");
$this->layout()->set("terminations", TerminationModel::getAll());
@@ -569,6 +673,9 @@ class ContractController extends mfBaseController
protected function editAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$id = $this->request->contract_id;
if (!$id) {
$id = $this->request->id;
@@ -602,6 +709,9 @@ class ContractController extends mfBaseController
protected function saveAction()
{
if(!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$r = $this->request;
//var_dump($r);
@@ -787,7 +897,7 @@ class ContractController extends mfBaseController
protected function apiAction()
{
if (!$this->me->is(["Admin"])) {
if (!$this->me->is(["Admin", "salespartner", "netowner"])) {
$this->redirect("Dashboard");
}
$do = $this->request->do;
@@ -797,8 +907,15 @@ class ContractController extends mfBaseController
case "getContract":
$return = $this->getContractApi();
break;
case "findContracts":
$return = $this->getContractsApi();
break;
case "findContract":
$return = $this->findContractApi();
break;
case "":
$return = "";
break;
default:
$return = false;
}
@@ -814,6 +931,10 @@ class ContractController extends mfBaseController
private function getContractApi()
{
if (!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$contract_id = $this->request->contract_id;
if (!is_numeric($contract_id) || $contract_id < 1) {
return false;
@@ -834,8 +955,58 @@ class ContractController extends mfBaseController
return ["contract" => $data, "form_id" => $form_id];
}
private function getContractsApi() {
$owner_id = $this->request->owner_id;
if(!$owner_id) return false;
$return = [];
$contracts = ContractModel::search(["owner_id" => $owner_id]);
if(!$contracts) {
header("Content-type: application/json");
echo json_encode([]);
exit;
}
$is_valid_owner = false;
if(!$this->me->is("Admin")) {
foreach($contracts as $contract) {
foreach(ContractLinkModel::includesContractId($contract->id) as $link) {
if($link->type != "credit") continue;
$link_contract = $link->contract;
if($link->contract_id == $contract->id) $link_contract = $link->origin;
if($link_contract->owner_id == $this->me->address_id) {
$is_valid_owner = true;
break;
}
}
}
if(!$is_valid_owner) {
header("Content-type: application/json");
echo json_encode([]);
exit;
}
}
foreach($contracts as $contract) {
$c = get_object_vars($contract->data);
$c["id"] = $contract->id;
$return[] = $c;
}
header("Content-type: application/json");
echo json_encode($return);
exit;
}
private function findContractApi()
{
if (!$this->me->is(["Admin"])) {
$this->redirect("Dashboard");
}
$search = trim($this->request->q);
$autocomplete = $this->request->autocomplete;

View File

@@ -48,6 +48,7 @@ class ContractTrigger_Finished {
$now->setTime(2,0,0);
$cancel_date = clone($now);
$cancel_date->modify("-1 day");
$cancel_date->setTime(23,59,59);
$origin = $link->origin;
@@ -74,7 +75,7 @@ class ContractTrigger_Finished {
// verlinkten Contract kündigen (wenn nicht schon gekündigt)
if ($old_link->change_action == "cancel" && !$old_link->origin->cancel_date) {
$old_link->origin->update([
'cancel_date' => $now->getTimestamp(),
'cancel_date' => $cancel_date->getTimestamp(),
'cancel_date_by' => $this->me->id,
'edit_by' => $this->me->id
]);
@@ -100,7 +101,7 @@ class ContractTrigger_Finished {
// verlinkten Contract kündigen (wenn nicht schon gekündigt)
if ($old_link->change_action == "cancel" && !$old_link->contract->cancel_date) {
$old_link->contract->update([
'cancel_date' => $now->getTimestamp(),
'cancel_date' => $cancel_date->getTimestamp(),
'cancel_date_by' => $this->me->id,
'edit_by' => $this->me->id
]);
@@ -126,7 +127,7 @@ class ContractTrigger_Finished {
// Alte Gutschrift kündigen und neue anlegen
//var_dump($old_credit->contract);
$old_credit->contract->update([
'cancel_date' => $now->getTimestamp(),
'cancel_date' => $cancel_date->getTimestamp(),
'cancel_date_by' => $this->me->id,
'edit_by' => $this->me->id
]);

View File

@@ -150,18 +150,11 @@ class OrderController extends mfBaseController {
}
}
//if(!$showLonelies) {
//var_dump($order_search);exit;
$pagination['maxItems'] = OrderModel::count($order_search);
foreach(OrderModel::search($order_search, $pagination) as $order) {
if(!array_key_exists($order->id, $orders)) {
$orders[$order->id] = $order;
}
}
//}
$pagination['maxItems'] = OrderModel::count($order_search);
$orders = OrderModel::search($order_search, $pagination, true);
$showLoneliesCount = false;
foreach(["owner", "owner_address", "partner_number"] as $key) {
foreach(["owner", "owner_address", "partner_number"] as $key) {
if(array_key_exists($key, $filter) && $filter[$key]) {
$showLoneliesCount = true;
break;
@@ -192,7 +185,6 @@ class OrderController extends mfBaseController {
if($this->me->isAdmin()) {
if(!$this->request->filter['network_id']) {
$lonelies = OrderModel::search($order_search);
}
} else {
$order_search['create_by'] = $userIds;
@@ -225,7 +217,7 @@ class OrderController extends mfBaseController {
foreach($lonelies as $order) {
// check for voice or special products only
$this->log->debug("Order id ".$order->id);
//$this->log->debug("Order id ".$order->id);
/*if($order->id == 38) {
var_dump($order);
exit;
@@ -379,18 +371,7 @@ class OrderController extends mfBaseController {
$users = [];
foreach($this->me->my_networks as $network) {
$network_ids[] = $network->id;
/*$tmp_users = $network->getAddressUsersByAddresstype("salespartner");
foreach($tmp_users as $user) {
if(!in_array($user->id, $users)) {
$users[] = $user->id;
}
}*/
}
/*
// get addresses from salespartner address' user ids
$addresses = AddressModel::search(["create_by" => $users]);
$this->layout()->set("addresses", $addresses);
*/
// get terminations in my networks
$terms = TerminationModel::search(["network_id" => $network_ids]);
$this->layout()->set("terminations", $terms);
@@ -445,6 +426,10 @@ class OrderController extends mfBaseController {
return $this->addAction();
}
protected function upgradesAction() {
}
protected function setwaitingAction() {
$order_id = $this->request->id;
@@ -476,7 +461,73 @@ class OrderController extends mfBaseController {
$this->layout()->setFlash("Wartestatus erfolgreich gespeichert", "success");
$this->redirect("Order","Index", $qs);
}
protected function addUpgrade() {
//$this->layout()->setTemplate("Order/Productchange");
Helper::renderVue($this, "OrderProductchange", "Neuer Produktwechsel", ["CONTRACT_API_URL" => $this->getUrl("Contract", "api"),
"ADDRESS_API_URL" => $this->getUrl("Address", "api"),
"ORDER_PRODUCTCHANGE_URL" => $this->getUrl("Order", "productchange")]);
}
protected function productchangeAction() {
$this->layout()->setTemplate("Order/ProductchangeForm");
$f = $this->request->f;
if(!$f) {
$f = "c"; // from Contract
}
$this->layout()->set("f", $f);
$id = $this->request->contract_id;
if (!$id) {
$id = $this->request->id;
}
if (!is_numeric($id) || !$id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Order", "addUpgrade");
}
$contract = new Contract($id);
if (!$contract->id) {
$this->layout()->setFlash("Vertrag nicht gefunden", "error");
$this->redirect("Order", "addUpgrade");
}
if($this->me->isAdmin()) {
$this->layout()->set("terminations", TerminationModel::getAll());
} else {
// check permissions
// check if correct network
$my_network_ids = [];
foreach($this->me->my_networks as $network) {
$my_network_ids[] = $network->id;
}
if($contract->termination_id) {
if(!in_array($contract->termination->network_id, $my_network_ids)) {
$this->layout()->setFlash("Keine Berechtigung", "error");
$this->redirect("Order", "addUpgrade", ["owner_id" => $contract->owner_id]);
}
}
$terms = TerminationModel::search(["network_id" => $my_network_ids]);
$this->layout()->set("terminations", $terms);
}
$this->layout()->set("contract", $contract);
if ($this->request->filter) {
$this->layout()->set("filter", $this->request->filter);
}
if ($this->request->s) {
$this->layout()->set("filter", $this->request->s);
}
}
protected function saveAction() {
$r = $this->request;
//var_dump($r->products);

View File

@@ -180,7 +180,7 @@ class OrderModel {
return 0;
}
public static function search($filter, $limit=false) {
public static function search($filter, $limit=false, $withId = false) {
$items = [];
$db = FronkDB::singleton();
@@ -210,7 +210,7 @@ class OrderModel {
if(is_array($limit) && count($limit)) {
if(is_numeric($limit['start']) && is_numeric($limit['count'])) {
$sql .= " LIMIT ".$limit['start'].", ".$limit['count'];
} elseif(is_numeric($count)) {
} elseif(is_numeric($limit['count'])) {
$sql .= " LIMIT ".$limit['count'];
}
}
@@ -218,7 +218,11 @@ class OrderModel {
$res = $db->query($sql);
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new Order($data);
if($withId) {
$items[$data->id] = new Order($data);
} else {
$items[] = new Order($data);
}
}
}

View File

@@ -421,9 +421,32 @@ class ProductController extends mfBaseController {
}
$results = [];
if(!$this->me->isAdmin()) {
$my_product_ids = [];
$my_network_ids = [];
foreach($this->me->my_networks as $network) {
$my_network_ids[] = $network->id;
}
foreach(ProductNetworkModel::search(["network_id" => $my_network_ids]) as $pn) {
if(!$pn->product->active) continue;
if(!array_key_exists($pn->product_id, $my_product_ids)) {
$my_product_ids[] = $pn->product_id;
}
}
}
// return bootstrap-autocomplete format
foreach($products as $product) {
if(!$this->me->isAdmin()) {
if(!in_array($product->id, $my_product_ids)) continue;
}
$result = ['value' => $product->id, 'text' => str_replace("'", "\\'", str_replace(["\n", "\r"], " ",$product->name))];
$results[] = $result;
if(count($results) > 15) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

View File

@@ -0,0 +1,40 @@
.leaflet-control-fullscreen a {
background:#fff url(fullscreen.png) no-repeat 0 0;
background-size:26px 52px;
}
.leaflet-touch .leaflet-control-fullscreen a {
background-position: 2px 2px;
}
.leaflet-fullscreen-on .leaflet-control-fullscreen a {
background-position:0 -26px;
}
.leaflet-touch.leaflet-fullscreen-on .leaflet-control-fullscreen a {
background-position: 2px -24px;
}
/* Do not combine these two rules; IE will break. */
.leaflet-container:-webkit-full-screen {
width:100%!important;
height:100%!important;
}
.leaflet-container.leaflet-fullscreen-on {
width:100%!important;
height:100%!important;
}
.leaflet-pseudo-fullscreen {
position:fixed!important;
width:100%!important;
height:100%!important;
top:0!important;
left:0!important;
z-index:99999;
}
@media
(-webkit-min-device-pixel-ratio:2),
(min-resolution:192dpi) {
.leaflet-control-fullscreen a {
background-image:url(fullscreen@2x.png);
}
}

View File

@@ -0,0 +1 @@
(function(factory){var L;if(typeof define==="function"&&define.amd){define(["leaflet"],factory)}else if(typeof module!=="undefined"){L=require("leaflet");module.exports=factory(L)}else{if(typeof window.L==="undefined"){throw new Error("Leaflet must be loaded first")}factory(window.L)}})(function(L){L.Control.Fullscreen=L.Control.extend({options:{position:"topleft",title:{"false":"View Fullscreen","true":"Exit Fullscreen"}},onAdd:function(map){var container=L.DomUtil.create("div","leaflet-control-fullscreen leaflet-bar leaflet-control");this.link=L.DomUtil.create("a","leaflet-control-fullscreen-button leaflet-bar-part",container);this.link.href="#";this._map=map;this._map.on("fullscreenchange",this._toggleTitle,this);this._toggleTitle();L.DomEvent.on(this.link,"click",this._click,this);return container},_click:function(e){L.DomEvent.stopPropagation(e);L.DomEvent.preventDefault(e);this._map.toggleFullscreen(this.options)},_toggleTitle:function(){this.link.title=this.options.title[this._map.isFullscreen()]}});L.Map.include({isFullscreen:function(){return this._isFullscreen||false},toggleFullscreen:function(options){var container=this.getContainer();if(this.isFullscreen()){if(options&&options.pseudoFullscreen){this._disablePseudoFullscreen(container)}else if(document.exitFullscreen){document.exitFullscreen()}else if(document.mozCancelFullScreen){document.mozCancelFullScreen()}else if(document.webkitCancelFullScreen){document.webkitCancelFullScreen()}else if(document.msExitFullscreen){document.msExitFullscreen()}else{this._disablePseudoFullscreen(container)}}else{if(options&&options.pseudoFullscreen){this._enablePseudoFullscreen(container)}else if(container.requestFullscreen){container.requestFullscreen()}else if(container.mozRequestFullScreen){container.mozRequestFullScreen()}else if(container.webkitRequestFullscreen){container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}else if(container.msRequestFullscreen){container.msRequestFullscreen()}else{this._enablePseudoFullscreen(container)}}},_enablePseudoFullscreen:function(container){L.DomUtil.addClass(container,"leaflet-pseudo-fullscreen");this._setFullscreen(true);this.fire("fullscreenchange")},_disablePseudoFullscreen:function(container){L.DomUtil.removeClass(container,"leaflet-pseudo-fullscreen");this._setFullscreen(false);this.fire("fullscreenchange")},_setFullscreen:function(fullscreen){this._isFullscreen=fullscreen;var container=this.getContainer();if(fullscreen){L.DomUtil.addClass(container,"leaflet-fullscreen-on")}else{L.DomUtil.removeClass(container,"leaflet-fullscreen-on")}this.invalidateSize()},_onFullscreenChange:function(e){var fullscreenElement=document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement;if(fullscreenElement===this.getContainer()&&!this._isFullscreen){this._setFullscreen(true);this.fire("fullscreenchange")}else if(fullscreenElement!==this.getContainer()&&this._isFullscreen){this._setFullscreen(false);this.fire("fullscreenchange")}}});L.Map.mergeOptions({fullscreenControl:false});L.Map.addInitHook(function(){if(this.options.fullscreenControl){this.fullscreenControl=new L.Control.Fullscreen(this.options.fullscreenControl);this.addControl(this.fullscreenControl)}var fullscreenchange;if("onfullscreenchange"in document){fullscreenchange="fullscreenchange"}else if("onmozfullscreenchange"in document){fullscreenchange="mozfullscreenchange"}else if("onwebkitfullscreenchange"in document){fullscreenchange="webkitfullscreenchange"}else if("onmsfullscreenchange"in document){fullscreenchange="MSFullscreenChange"}if(fullscreenchange){var onFullscreenChange=L.bind(this._onFullscreenChange,this);this.whenReady(function(){L.DomEvent.on(document,fullscreenchange,onFullscreenChange)});this.on("unload",function(){L.DomEvent.off(document,fullscreenchange,onFullscreenChange)})}});L.control.fullscreen=function(options){return new L.Control.Fullscreen(options)}});

View File

@@ -0,0 +1,94 @@
Vue.component('OrderProductchange', {
//language=Vue
template: `
<tt-card style="min-height:50vh;" class="border-top-purple">
<div class="row">
<div class="col">
<p class="alert alert-purple">Wählen Sie den Vertragsinhaber aus, um die aktiven Produkte anzuzeigen.<br />
Produktwechsel sollten immer mit dem Hauptprodukt durchgeführt werden. Dies ist fast immer das Internetzugangsprodukt.</p>
<tt-autocomplete :api-url="window['TT_CONFIG']['ADDRESS_API_URL'] + '?do=findAddress'"
v-model="owner_id" label="Vertragsinhaber suchen" placeholder="Tippen zum Suchen..."></tt-autocomplete>
<div v-if="owner_id !== ''">
<tt-card class="col-6" v-if="owner_id !== '' && typeof owner === 'object'">
{{owner.name}}<br/>
{{owner.street}}<br/>
{{owner.zip}} {{owner.city}}
</tt-card>
<tt-table
:fetch-url="\`\${window['TT_CONFIG']['CONTRACT_API_URL']}?do=findContracts&owner_id=\${owner_id}\`"
:config="OrderProductchangeTableConfig" :small="false" class="sm"
disable-filtering ref="contractTable">
<template v-slot:actions="{ row }">
<a :href="window['TT_CONFIG']['ORDER_PRODUCTCHANGE_URL'] + '?contract_id=' + row.id"
class="btn btn-purple"><i class="fas fa-fw fa-square-up"></i> Produktwechsel erstellen</a>
</template>
<template v-slot:billing_period="{ row }">
<span v-if="row.billing_period == 1">Monatlich</span>
<span v-else-if="row.billing_period == 12">Jährlich</span>
<span v-else-if="row.billing_period == 0">Einmalig</span>
<span v-else>{{row.billing_period}}</span>
</template>
<template v-slot:finish_date="{ row }">
<span v-if="row.finish_date > 0">{{window.moment.unix(row.finish_date).isValid() ? window.moment.unix(row.finish_date).format('DD.MM.YYYY') : ''}}</span>
</template>
<template v-slot:cancel_date="{ row }">
<span v-if="row.cancel_date > 0">{{window.moment.unix(row.cancel_date).isValid() ? window.moment.unix(row.cancel_date).format('DD.MM.YYYY') : ''}}</span>
</template>
<template v-slot:price="{ row }">
<span :class="(row.price < 0) ? 'text-danger' : ''">€ {{row.price | formatPrice}}</span>
</template>
<template v-slot:price_setup="{ row }">
<span :class="(row.price_setup < 0) ? 'text-danger' : ''">€ {{row.price_setup | formatPrice}}</span>
</template>
</tt-table>
</div>
</div>
</div>
</tt-card>
`, data() {
return {
window: window,
OrderProductchangeTableConfig: {
headers: [
{text: "", key: "actions", class: "text-right", headerClass: "text-right"},
{text: "Contract ID", key: "id", class: "text-right", headerClass: "text-right"},
{text: "Produkt", key: "product_name", headerClass: "text-left"},
{text: "Matchcode", key: "matchcode", headerClass: "text-left"},
{text: "Preis", key: "price", headerClass: "text-left"},
{text: "Periode", key: "billing_period", headerClass: "text-left"},
{text: "Herstellungskosten", key: "price_setup", headerClass: "text-left"},
{text: "Fertigstellung", key: "finish_date", filter: "date", headerClass: "text-left"},
{text: "Kündigung", key: "cancel_date", filter: "date", headerClass: "text-left"}
],
tableHeader: 'Zu änderndes Produkt wählen',
key: 'OrderProductchange',
},
owner_id: "",
owner: false
}
},
filters: {
formatPrice(price) {
roundedPrice = Math.round((parseFloat(price) + Number.EPSILON) * 100) / 100;
return roundedPrice.toFixed(4);
}
},
beforeMount() {
const urlSearchParams = new URLSearchParams(window.location.search);
if (urlSearchParams.has("owner_id")) {
this.owner_id = urlSearchParams.get("owner_id");
}
}
})