2022-10-18 13:41:34 +02:00
|
|
|
<?php
|
2023-02-27 10:39:04 +01:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2022 Andreas Palm
|
|
|
|
* SPDX-License-Identifier: LicenseRef-EGPL-3.1
|
|
|
|
*/
|
2022-10-18 13:41:34 +02:00
|
|
|
|
|
|
|
use Xentral\Modules\SubscriptionCycle\Service\SubscriptionCycleJobService;
|
|
|
|
use Xentral\Modules\SubscriptionCycle\SubscriptionModule;
|
|
|
|
|
|
|
|
class Rechnungslauf {
|
|
|
|
/** @var Application $app */
|
|
|
|
protected $app;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Application $app
|
|
|
|
* @param string $name
|
|
|
|
* @param array $erlaubtevars
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public static function TableSearch($app, $name, $erlaubtevars)
|
|
|
|
{
|
|
|
|
// in dieses switch alle lokalen Tabellen (diese Live Tabellen mit Suche etc.) für dieses Modul
|
|
|
|
switch($name)
|
|
|
|
{
|
|
|
|
case 'rechnungslauf_invoices':
|
|
|
|
case 'rechnungslauf_orders':
|
|
|
|
if ($name == 'rechnungslauf_invoices')
|
|
|
|
$doctype = 'rechnung';
|
|
|
|
else
|
|
|
|
$doctype = 'auftrag';
|
|
|
|
$allowed['rechnungslauf'] = ['rechnungslauf'];
|
|
|
|
|
|
|
|
$heading = array('', '', 'Kunden Nr.', 'Firma/Name', 'Anschreiben', 'E-Mail', 'Projekt', 'Von', 'Bis', 'Betrag netto', 'Menü');
|
|
|
|
$width = ['1%', '1%', '10%', '20%', '10%', '10%', '10%', '10%', '10%', '10%', '1%'];
|
|
|
|
|
|
|
|
$findcols = [
|
2023-03-23 22:28:48 +01:00
|
|
|
'adr.kundennummer',
|
|
|
|
'adr.kundennummer',
|
2022-10-18 13:41:34 +02:00
|
|
|
'adr.kundennummer',
|
|
|
|
'adr.name',
|
|
|
|
'adr.anschreiben',
|
|
|
|
"adr.email",
|
|
|
|
'p.abkuerzung',
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null
|
|
|
|
];
|
|
|
|
$searchsql = ['adr.kundennummer', 'adr.name', 'adr.email'];
|
|
|
|
|
|
|
|
$numbercols = [2, 10];
|
|
|
|
$alignright = [3, 10];
|
|
|
|
$datecols = [7, 8];
|
|
|
|
|
|
|
|
$defaultorder = 3;
|
|
|
|
$defaultorderdesc = 0;
|
|
|
|
$sumcol = [10];
|
|
|
|
|
|
|
|
$menu = '<table cellpadding="0" cellspacing="0">';
|
|
|
|
$menu .= '<tr>';
|
|
|
|
$menu .= '<td nowrap>';
|
|
|
|
$menu .= '<a href="index.php?module=adresse&action=artikel&id=%value%">';
|
|
|
|
$menu .= '<img src="themes/' . $app->Conf->WFconf['defaulttheme'] . '/images/forward.svg" border="0">';
|
|
|
|
$menu .= '</a>';
|
|
|
|
$menu .= '</td>';
|
|
|
|
$menu .= '</tr>';
|
|
|
|
$menu .= '</table>';
|
|
|
|
|
|
|
|
$calcdate = new \DateTimeImmutable('today');
|
|
|
|
$scalcdate = $calcdate->format('Y-m-d');
|
|
|
|
$where = " aa.id > 0
|
|
|
|
AND aa.dokument = '$doctype'
|
|
|
|
AND greatest(aa.startdatum, aa.abgerechnetbis) < '$scalcdate'
|
|
|
|
AND (aa.enddatum = '0000-00-00' OR aa.abgerechnetbis < aa.enddatum)";
|
|
|
|
|
|
|
|
$sql = "SELECT SQL_CALC_FOUND_ROWS
|
|
|
|
adr.id,
|
|
|
|
'<img src=\"./themes/new/images/details_open.png\" class=\"details\">' as open,
|
|
|
|
concat('<input type=\"checkbox\" name=\"selection[]\" value=\"',adr.id,'\" />') as auswahl,
|
|
|
|
adr.kundennummer,
|
|
|
|
adr.name,
|
|
|
|
adr.anschreiben,
|
|
|
|
adr.email,
|
|
|
|
p.abkuerzung,
|
|
|
|
GROUP_CONCAT(DATE_FORMAT(@start := GREATEST(aa.startdatum, aa.abgerechnetbis),'%d.%m.%Y') SEPARATOR '<br>') as start,
|
|
|
|
GROUP_CONCAT(DATE_FORMAT(
|
|
|
|
@end := CASE
|
|
|
|
WHEN aa.preisart = 'monat' THEN
|
|
|
|
DATE_ADD(@start, INTERVAL TIMESTAMPDIFF(MONTH, @start, IF(aa.enddatum = '0000-00-00' OR aa.enddatum > '$scalcdate', '$scalcdate', aa.enddatum))+1 MONTH)
|
|
|
|
WHEN aa.preisart = 'jahr' THEN
|
|
|
|
DATE_ADD(@start, INTERVAL TIMESTAMPDIFF(YEAR, @start, IF(aa.enddatum = '0000-00-00' OR aa.enddatum > '$scalcdate', '$scalcdate', aa.enddatum))+1 YEAR)
|
|
|
|
WHEN aa.preisart = '30tage' THEN
|
|
|
|
DATE_ADD(@start, INTERVAL (FLOOR(TIMESTAMPDIFF(DAY, @start, IF(aa.enddatum = '0000-00-00' OR aa.enddatum > '$scalcdate', '$scalcdate', aa.enddatum)) / 30)+1)*30 DAY )
|
|
|
|
END, '%d.%m.%Y') SEPARATOR '<br>') as end,
|
|
|
|
SUM((100-aa.rabatt)/100 * aa.preis * aa.menge *
|
2023-09-19 13:59:38 +02:00
|
|
|
(GREATEST(aa.zahlzyklus, CASE
|
2022-10-18 13:41:34 +02:00
|
|
|
WHEN aa.preisart = 'monat' THEN
|
|
|
|
TIMESTAMPDIFF(MONTH, @start, @end)
|
|
|
|
WHEN aa.preisart = 'jahr' THEN
|
|
|
|
TIMESTAMPDIFF(YEAR, @start, @end)
|
|
|
|
WHEN aa.preisart = '30tage' THEN
|
|
|
|
FLOOR(TIMESTAMPDIFF(DAY, @start, @end) / 30)
|
|
|
|
END
|
2023-09-19 13:59:38 +02:00
|
|
|
))
|
2022-10-18 13:41:34 +02:00
|
|
|
) as amount,
|
|
|
|
adr.id
|
|
|
|
FROM abrechnungsartikel aa
|
|
|
|
JOIN artikel a ON aa.artikel = a.id
|
|
|
|
JOIN adresse adr ON aa.adresse = adr.id
|
|
|
|
LEFT JOIN projekt p ON aa.projekt = p.id";
|
|
|
|
|
|
|
|
$groupby = " GROUP BY aa.adresse, aa.projekt";
|
|
|
|
|
|
|
|
$count = "SELECT count(aa.id)
|
|
|
|
FROM `abrechnungsartikel` AS `aa`
|
|
|
|
WHERE $where $groupby";
|
|
|
|
$menucol = 10;
|
|
|
|
$moreinfo = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'rechnungslauf_abos':
|
|
|
|
$allowed['rechnungslauf'] = ['abos'];
|
|
|
|
$heading = array(
|
|
|
|
'Kunde',
|
|
|
|
'Kunden Nr.',
|
|
|
|
'Bezeichnung',
|
|
|
|
'Nummer',
|
|
|
|
'Abgerechnet bis',
|
|
|
|
'Enddatum',
|
|
|
|
'Preis',
|
|
|
|
'Rabatt',
|
|
|
|
'Menge',
|
|
|
|
'Art',
|
|
|
|
'Zahlperiode',
|
|
|
|
'Zahlweise',
|
|
|
|
'Dokument',
|
|
|
|
'Menü');
|
|
|
|
$width = ['10%','5%','15%','1','1','1','1','1','1','1','1','1','1','1'];
|
|
|
|
|
|
|
|
$findcols = [
|
|
|
|
'ad.name',
|
|
|
|
'ad.kundennummer',
|
|
|
|
'aa.bezeichnung',
|
|
|
|
'a.nummer',
|
|
|
|
"DATE_FORMAT(aa.abgerechnetbis, '%d.%m.%Y')",
|
|
|
|
'aa.enddatum',
|
|
|
|
'aa.preis',
|
|
|
|
'aa.rabatt',
|
|
|
|
'aa.menge',
|
|
|
|
'aa.preisart',
|
|
|
|
'aa.zahlzyklus',
|
|
|
|
'',
|
|
|
|
'aa.dokument'
|
|
|
|
];
|
|
|
|
$searchsql = ['ad.name', 'aa.bezeichnung'];
|
|
|
|
|
|
|
|
$numbercols = [0];
|
|
|
|
$alignright = [7];
|
|
|
|
$datecols = [5,6];
|
|
|
|
|
|
|
|
$defaultorder = 1;
|
|
|
|
$defaultorderdesc = 0;
|
|
|
|
|
|
|
|
$menu = "<table cellpadding=0 cellspacing=0><tr><td nowrap>"
|
|
|
|
. "<a href=\"index.php?module=adresse&action=artikel&id=%value%\">"
|
|
|
|
. "<img src=\"themes/{$app->Conf->WFconf['defaulttheme']}/images/forward.svg\" border=\"0\"></a>"
|
|
|
|
. " </td></tr></table>";
|
|
|
|
|
|
|
|
$where = " aa.id > 0 AND (aa.enddatum = '0000-00-00' OR aa.abgerechnetbis < aa.enddatum) ";
|
|
|
|
|
|
|
|
$sql = "SELECT SQL_CALC_FOUND_ROWS aa.id, ad.name, ad.kundennummer,
|
|
|
|
aa.bezeichnung, a.nummer, DATE_FORMAT(aa.abgerechnetbis, '%d.%m.%Y'),
|
|
|
|
DATE_FORMAT(aa.enddatum, '%d.%m.%Y'),
|
|
|
|
".$app->erp->FormatPreis('aa.preis', 2).", aa.rabatt, aa.menge,
|
|
|
|
aa.preisart, aa.zahlzyklus, '', aa.dokument, ad.id
|
|
|
|
FROM `abrechnungsartikel` AS `aa`
|
|
|
|
LEFT JOIN `adresse` AS `ad` ON aa.adresse = ad.id
|
|
|
|
LEFT JOIN `artikel` AS `a` ON aa.artikel = a.id";
|
|
|
|
|
|
|
|
$count = "SELECT count(aa.id)
|
|
|
|
FROM `abrechnungsartikel` AS `aa`
|
|
|
|
WHERE $where";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$erg = [];
|
|
|
|
|
|
|
|
foreach($erlaubtevars as $k => $v) {
|
|
|
|
if(isset($$v)) {
|
|
|
|
$erg[$v] = $$v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $erg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rechnungslauf constructor.
|
|
|
|
*
|
|
|
|
* @param Application $app
|
|
|
|
* @param bool $intern
|
|
|
|
*/
|
|
|
|
public function __construct($app, $intern = false) {
|
|
|
|
$this->app = $app;
|
|
|
|
if($intern) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$this->app->ActionHandlerInit($this);
|
|
|
|
|
|
|
|
// ab hier alle Action Handler definieren die das Modul hat
|
2023-03-23 22:28:48 +01:00
|
|
|
$this->app->ActionHandler('list', 'ActionList');
|
2022-10-18 13:41:34 +02:00
|
|
|
$this->app->ActionHandler('abos', 'ActionAbos');
|
|
|
|
$this->app->ActionHandler('minidetail', 'ActionMinidetail');
|
|
|
|
|
|
|
|
$this->app->ActionHandlerListen($app);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function MenuList() {
|
|
|
|
$this->app->erp->Headlines("Abolauf");
|
2023-03-23 22:28:48 +01:00
|
|
|
$this->app->erp->MenuEintrag("index.php?module=rechnungslauf&action=list", "Übersicht");
|
2022-10-18 13:41:34 +02:00
|
|
|
$this->app->erp->MenuEintrag("index.php?module=rechnungslauf&action=abos", "gebuchte Abos");
|
|
|
|
$this->app->erp->MenuEintrag("index.php?module=rechnungslauf&action=einstellungen", "Einstellungen");
|
|
|
|
}
|
|
|
|
|
|
|
|
public function ActionList() {
|
|
|
|
/** @var SubscriptionModule $module */
|
|
|
|
$this->MenuList();
|
|
|
|
$this->app->YUI->TableSearch("TAB_INVOICES", 'rechnungslauf_invoices','show', '', '', basename(__FILE__), __CLASS__);
|
|
|
|
$this->app->YUI->TableSearch("TAB_ORDERS", 'rechnungslauf_orders','show', '', '', basename(__FILE__), __CLASS__);
|
|
|
|
if ($this->app->Secure->GetPOST('createInvoices') !== '') {
|
|
|
|
$selection = $this->app->Secure->GetPOST('selection');
|
|
|
|
/** @var SubscriptionCycleJobService $subscriptionCycleJobService */
|
|
|
|
$subscriptionCycleJobService = $this->app->Container->get('SubscriptionCycleJobService');
|
|
|
|
foreach ($selection as $value) {
|
|
|
|
$subscriptionCycleJobService->deleteJobsByAddressIdAndDoctype($value, 'rechnung');
|
|
|
|
$subscriptionCycleJobService->create($value, 'rechnung');
|
2022-12-22 22:27:27 +01:00
|
|
|
$this->app->Tpl->addMessage('info', 'Die Rechnungen werden nun im Hintergrund erstellt', false, 'MESSAGE_INVOICES');
|
2022-10-18 13:41:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ($this->app->Secure->GetPOST('createOrders') !== '') {
|
|
|
|
$selection = $this->app->Secure->GetPOST('selection');
|
|
|
|
/** @var SubscriptionCycleJobService $subscriptionCycleJobService */
|
|
|
|
$subscriptionCycleJobService = $this->app->Container->get('SubscriptionCycleJobService');
|
|
|
|
foreach ($selection as $value) {
|
|
|
|
$subscriptionCycleJobService->deleteJobsByAddressIdAndDoctype($value, 'auftrag');
|
|
|
|
$subscriptionCycleJobService->create($value, 'auftrag');
|
2022-12-22 22:27:27 +01:00
|
|
|
$this->app->Tpl->addMessage('info', 'Die Aufträge werden nun im Hintergrund erstellt', false, 'MESSAGE_ORDERS');
|
2022-10-18 13:41:34 +02:00
|
|
|
}
|
|
|
|
}
|
2024-01-22 13:38:21 +01:00
|
|
|
|
|
|
|
$cronjobActive = $this->app->DB->Select(
|
|
|
|
"SELECT ps.id
|
|
|
|
FROM `prozessstarter` AS `ps`
|
|
|
|
WHERE ps.aktiv = 1 and (ps.parameter = 'rechnungslauf_manual')
|
|
|
|
LIMIT 1"
|
|
|
|
);
|
|
|
|
if(!$cronjobActive) {
|
|
|
|
$this->app->Tpl->addMessage('warning', 'Der Prozessstarter \'rechnungslauf_manual\' ist nicht aktiv');
|
|
|
|
}
|
|
|
|
|
2022-10-18 13:41:34 +02:00
|
|
|
$this->app->Tpl->Parse('PAGE', 'rechnungslauf_list.tpl');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function ActionAbos() {
|
|
|
|
$this->MenuList();
|
|
|
|
$this->app->YUI->TableSearch("TAB1", 'rechnungslauf_abos', 'show', '', '', basename(__FILE__), __CLASS__);
|
|
|
|
$this->app->Tpl->Parse('PAGE', 'rechnungslauf_abos.tpl');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function ActionMinidetail() {
|
|
|
|
/** @var SubscriptionModule $module */
|
|
|
|
$module = $this->app->Container->get('SubscriptionModule');
|
|
|
|
$address = $this->app->Secure->GetGET('id');
|
|
|
|
$pos = $module->GetPositions($address, 'rechnung');
|
|
|
|
foreach ($pos as $p) {
|
|
|
|
$row = '<tr>';
|
|
|
|
$row .= sprintf('<td>%s</td>', $p['bezeichnung']);
|
|
|
|
$row .= sprintf('<td>%s</td>', $p['menge']);
|
|
|
|
$row .= sprintf('<td style="text-align: right">%s</td>',
|
|
|
|
$this->app->erp->number_format_variable($p['preis'], 2));
|
|
|
|
$row .= sprintf('<td>%s</td>', $p['rabatt']);
|
|
|
|
$row .= sprintf('<td>%s</td>', $p['cycles']);
|
|
|
|
$row .= sprintf('<td style="text-align: right">%s</td>',
|
|
|
|
$this->app->erp->number_format_variable($p['preis']*$p['menge']*$p['cycles'], 2));
|
|
|
|
$row .= sprintf('<td>%s</td>', $p['waehrung']);
|
|
|
|
$row .= '</tr>';
|
|
|
|
$this->app->Tpl->Add('INHALT', $row);
|
|
|
|
}
|
|
|
|
$this->app->Tpl->Set('SUBHEADING', 'Kunde');
|
|
|
|
$this->app->Tpl->Output('rechnungslauf_minidetail.tpl');
|
|
|
|
$this->app->ExitXentral();
|
|
|
|
}
|
2024-01-22 13:38:21 +01:00
|
|
|
}
|