diff --git a/classes/Modules/SubscriptionCycle/Bootstrap.php b/classes/Modules/SubscriptionCycle/Bootstrap.php index 8e5fdb0b..a27c4664 100644 --- a/classes/Modules/SubscriptionCycle/Bootstrap.php +++ b/classes/Modules/SubscriptionCycle/Bootstrap.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Xentral\Modules\SubscriptionCycle; use Aboabrechnung; +use Sabre\CalDAV\Subscriptions\Subscription; use Xentral\Components\SchemaCreator\Collection\SchemaCollection; use Xentral\Components\SchemaCreator\Schema\TableSchema; use Xentral\Components\SchemaCreator\Type; @@ -35,6 +36,7 @@ final class Bootstrap 'SubscriptionCycleJobService' => 'onInitSubscriptionCycleJobService', 'SubscriptionCycleFullTask' => 'onInitSubscriptionCycleFullTask', 'TaskMutexService' => 'onInitTaskMutexService', + 'SubscriptionModule' => 'onInitSubscriptionModule' ]; } @@ -60,20 +62,12 @@ final class Bootstrap */ public static function onInitSubscriptionCycleManualJobTask(ContainerInterface $container ): SubscriptionCycleManualJobTask { - $legacyApp = $container->get('LegacyApplication'); - - $subscriptionCycleModule = $legacyApp->loadModule('rechnungslauf'); - $subscriptionModule = new Aboabrechnung($legacyApp); - $subscriptionModule->cronjob = true; - return new SubscriptionCycleManualJobTask( - $legacyApp, + $container->get('LegacyApplication'), $container->get('Database'), $container->get('TaskMutexService'), $container->get('SubscriptionCycleJobService'), - $subscriptionCycleModule, - $subscriptionModule, - !empty($legacyApp->erp->GetKonfiguration('rechnungslauf_gruppen')) + $container->get('SubscriptionModule') ); } @@ -210,22 +204,10 @@ final class Bootstrap ); } - /** - * @param SchemaCollection $collection - * - * @return void - */ - public static function registerTableSchemas(SchemaCollection $collection): void - { - $subscriptionCycleJob = new TableSchema('subscription_cycle_job'); - $subscriptionCycleJob->addColumn(Type\Integer::asAutoIncrement('id')); - $subscriptionCycleJob->addColumn(new Type\Integer('address_id')); - $subscriptionCycleJob->addColumn(new Type\Varchar('document_type', 32)); - $subscriptionCycleJob->addColumn(new Type\Varchar('job_type', 32)); - $subscriptionCycleJob->addColumn(new Type\Integer('printer_id')); - $subscriptionCycleJob->addColumn(new Type\Timestamp('created_at', 'CURRENT_TIMESTAMP')); - $subscriptionCycleJob->addIndex(new Index\Primary(['id'])); - $subscriptionCycleJob->addIndex(new Index\Index(['address_id'])); - $collection->add($subscriptionCycleJob); + public static function onInitSubscriptionModule(ContainerInterface $container): SubscriptionModule { + return new SubscriptionModule( + $container->get('LegacyApplication'), + $container->get('Database') + ); } } diff --git a/classes/Modules/SubscriptionCycle/Scheduler/SubscriptionCycleManualJobTask.php b/classes/Modules/SubscriptionCycle/Scheduler/SubscriptionCycleManualJobTask.php index b7b4b03a..f7378baa 100644 --- a/classes/Modules/SubscriptionCycle/Scheduler/SubscriptionCycleManualJobTask.php +++ b/classes/Modules/SubscriptionCycle/Scheduler/SubscriptionCycleManualJobTask.php @@ -16,52 +16,33 @@ use Xentral\Modules\SubscriptionCycle\SubscriptionModuleInterface; final class SubscriptionCycleManualJobTask { - /** @var ApplicationCore $app */ - private $app; + private ApplicationCore $app; + private Database $db; + private SubscriptionCycleJobService $cycleJobService; + private TaskMutexServiceInterface $taskMutexService; + private SubscriptionModuleInterface $subscriptionModule; - /** @var Database $db */ - private $db; - - /** @var SubscriptionCycleJobService $cycleJobService */ - private $cycleJobService; - - /** @var TaskMutexServiceInterface $taskMutexService */ - private $taskMutexService; - - /** @var SubscriptionCycleModuleInterface $subscriptionCycleModule */ - private $subscriptionCycleModule; - - /** @var SubscriptionModuleInterface $subscriptionModule */ - private $subscriptionModule; - - /** @var bool $useGroups */ - private $useGroups; - - /** - * SubscriptionCycleManualJobTask constructor. - * - * @param ApplicationCore $app - * @param Database $db - * @param SubscriptionCycleJobService $cycleJobService - * @param SubscriptionCycleModuleInterface $subscriptionCycleModule - * @param bool $useGroups - */ + /** + * SubscriptionCycleManualJobTask constructor. + * + * @param ApplicationCore $app + * @param Database $db + * @param TaskMutexServiceInterface $taskMutexService + * @param SubscriptionCycleJobService $cycleJobService + * @param SubscriptionModuleInterface $subscriptionModule + */ public function __construct( ApplicationCore $app, Database $db, TaskMutexServiceInterface $taskMutexService, SubscriptionCycleJobService $cycleJobService, - SubscriptionCycleModuleInterface $subscriptionCycleModule, SubscriptionModuleInterface $subscriptionModule, - bool $useGroups ) { $this->app = $app; $this->db = $db; $this->taskMutexService = $taskMutexService; $this->cycleJobService = $cycleJobService; - $this->subscriptionCycleModule = $subscriptionCycleModule; $this->subscriptionModule = $subscriptionModule; - $this->useGroups = $useGroups; } public function execute(): void @@ -71,77 +52,16 @@ final class SubscriptionCycleManualJobTask } $this->taskMutexService->setMutex('rechnungslauf_manual'); $jobs = $this->cycleJobService->listAll(100); - $simulatedDays = $this->getSimulatedDates($jobs); - if (empty($jobs)) { - return; - } - foreach (['auftrag', 'rechnung'] as $doctype) { - foreach ($simulatedDays as $simulatedDay) { - if ($simulatedDay === '') { - $simulatedDay = null; - } else { - try { - $simulatedDay = new DateTimeImmutable($simulatedDay); - } catch (Exception $exception) { - $simulatedDay = null; - } - } - $addresses = $this->getAddressesByTypeFromJobs($jobs, $doctype, $simulatedDay); - foreach ($jobs as $job) { - $job = $this->cycleJobService->getJob((int)$job['id']); - if (empty($job)) { - continue; - } - if ($job['document_type'] !== $doctype) { - continue; - } - if ($job['simulated_day'] === null && $simulatedDay !== null) { - continue; - } - if ( - $job['simulated_day'] !== null - && ($simulatedDay === null || $simulatedDay->format('Y-m-d') !== $job['simulated_day']) - ) { - continue; - } - if (!in_array($job['address_id'], $addresses, false)) { - $this->cycleJobService->delete((int)$job['id']); - continue; - } - $simulatedDay = null; - if ($job['simulated_day'] !== null) { - try { - $simulatedDay = new DateTimeImmutable($job['simulated_day']); - } catch (Exception $exception) { - $simulatedDay = null; - } - } - if ($this->useGroups) { - $this->subscriptionCycleModule->generateAndSendSubscriptionCycleGroups( - $this->subscriptionModule, - [$job['address_id']], - $doctype, - $job['job_type'], - $job['printer_id'], - $simulatedDay - ); - } else { - $this->subscriptionCycleModule->generateAndSendSubscriptionCycle( - $this->subscriptionModule, - [$job['address_id']], - $doctype, - $job['printer_id'], - $job['job_type'], - $simulatedDay - ); - } - $this->cycleJobService->delete((int)$job['id']); - if ($this->taskMutexService->isTaskInstanceRunning('rechnungslauf')) { - return; - } - $this->taskMutexService->setMutex('rechnungslauf_manual'); - } - } + foreach ($jobs as $job) { + switch ($job['document_type']) { + case 'rechnung': + $this->subscriptionModule->CreateInvoice((int)$job['address_id']); + break; + case 'auftrag': + $this->subscriptionModule->CreateOrder((int)$job['address_id']); + break; + } + $this->cycleJobService->delete((int)$job['id']); } } @@ -149,52 +69,4 @@ final class SubscriptionCycleManualJobTask { $this->taskMutexService->setMutex('rechnungslauf_manual', false); } - - /** - * @param array $jobs - * @param string $documentType - * @param DateTimeInterface|null $simulatedDay - * - * @return array - */ - private function getAddressesByTypeFromJobs( - array $jobs, - string $documentType, - ?DateTimeInterface $simulatedDay = null - ): array { - $addresses = []; - foreach ($jobs as $job) { - if ($job['document_type'] === $documentType) { - $addresses[] = (int)$job['address_id']; - } - } - - if (empty($addresses)) { - return []; - } - - $addressesWithSubscriptions = array_keys( - (array)$this->subscriptionModule->GetRechnungsArray($documentType, true) - ); - - return array_intersect($addresses, $addressesWithSubscriptions); - } - - /** - * get all Dates from Setting "Vergangenes Datum für Abrechnungserstellung" to calc old Subscription cycles - * - * @param array $jobs - * - * @return array - */ - private function getSimulatedDates(array $jobs): array - { - $simulatedDates = []; - foreach ($jobs as $job) { - $simulatedDates[] = (string)$job['simulated_day']; - } - - return array_unique($simulatedDates); - } - } diff --git a/classes/Modules/SubscriptionCycle/Service/SubscriptionCycleJobService.php b/classes/Modules/SubscriptionCycle/Service/SubscriptionCycleJobService.php index 802d138f..5d5c106b 100644 --- a/classes/Modules/SubscriptionCycle/Service/SubscriptionCycleJobService.php +++ b/classes/Modules/SubscriptionCycle/Service/SubscriptionCycleJobService.php @@ -11,7 +11,7 @@ use Xentral\Modules\SubscriptionCycle\Exception\InvalidArgumentException; final class SubscriptionCycleJobService { - private $db; + private Database $db; /** * SubscriptionCycleJobService constructor. @@ -57,29 +57,27 @@ final class SubscriptionCycleJobService * @param string $documentType * @param string|null $jobType * @param int|null $printerId - * @param DateTimeInterface|null $simulatedDay * * @throws InvalidArgumentException * * @return int */ - public function create(int $addressId, string $documentType, ?string $jobType, ?int $printerId, ?DateTimeInterface $simulatedDay = null): int + public function create(int $addressId, string $documentType, ?string $jobType = null, ?int $printerId = null): int { $this->ensureDocumentType($documentType); $this->db->perform( 'INSERT INTO `subscription_cycle_job` - (`address_id`, `document_type`, `job_type`, `printer_id`, `created_at`, `simulated_day`) - VALUES (:address_id, :document_type, :job_type, :printer_id, NOW(), :simulated_day)', + (`address_id`, `document_type`, `job_type`, `printer_id`, `created_at`) + VALUES (:address_id, :document_type, :job_type, :printer_id, NOW())', [ 'address_id' => $addressId, 'document_type' => $documentType, 'job_type' => $jobType, 'printer_id' => $printerId, - 'simulated_day' => $simulatedDay === null ? null : $simulatedDay->format('Y-m-d'), ] ); - return (int)$this->db->lastInsertId(); + return $this->db->lastInsertId(); } /** diff --git a/classes/Modules/SubscriptionCycle/SubscriptionModule.php b/classes/Modules/SubscriptionCycle/SubscriptionModule.php new file mode 100644 index 00000000..6adfcca6 --- /dev/null +++ b/classes/Modules/SubscriptionCycle/SubscriptionModule.php @@ -0,0 +1,101 @@ +app = $app; + $this->db = $db; + } + + public function GetPositions(int $address, string $documentType, DateTimeInterface $calculationDate = null): array + { + if ($calculationDate === null) + $calculationDate = new DateTimeImmutable('today'); + + $sql = "SELECT + aa.id, + @start := GREATEST(aa.startdatum, aa.abgerechnetbis) as start, + @end := IF(aa.enddatum = '0000-00-00' OR aa.enddatum > :calcdate, :calcdate, aa.enddatum) as end, + @cycles := CASE + 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+1 as cycles, + CASE + WHEN aa.preisart = 'monat' THEN + DATE_ADD(@start, INTERVAL @cycles MONTH) + WHEN aa.preisart = 'jahr' THEN + DATE_ADD(@start, INTERVAL @cycles YEAR) + WHEN aa.preisart = '30tage' THEN + DATE_ADD(@start, INTERVAL @cycles*30 DAY ) + END as newend, + aa.preisart, + aa.adresse, + aa.preis, + aa.rabatt, + aa.bezeichnung, + aa.beschreibung, + aa.artikel, + aa.menge, + aa.waehrung + FROM abrechnungsartikel aa + JOIN artikel a on aa.artikel = a.id + WHERE aa.dokument = :doctype + AND greatest(aa.startdatum, aa.abgerechnetbis) <= :calcdate + AND (aa.enddatum = '0000-00-00' OR aa.abgerechnetbis < aa.enddatum) + AND aa.adresse = :address"; + + return $this->db->fetchAll($sql, [ + 'doctype' => $documentType, + 'calcdate' => $calculationDate->format('Y-m-d'), + 'address' => $address]); + } + + public function CreateInvoice(int $address, DateTimeInterface $calculationDate = null) { + $positions = $this->GetPositions($address, 'rechnung', $calculationDate); + if(empty($positions)) + return; + + $invoice = $this->app->erp->CreateRechnung($address); + $this->app->erp->LoadRechnungStandardwerte($invoice, $address); + foreach ($positions as $pos) { + $beschreibung = $pos['beschreibung']; + $beschreibung .= "
Zeitraum: {$pos['start']} - {$pos['end']}"; + $this->app->erp->AddRechnungPositionManuell($invoice, $pos['artikel'], $pos['preis'], + $pos['menge']*$pos['cycles'], $pos['bezeichnung'], $beschreibung, $pos['waehrung'], $pos['rabatt']); + } + $this->app->erp->RechnungNeuberechnen($invoice); + $this->app->erp->BelegFreigabe('rechnung', $invoice); + } + + public function CreateOrder(int $address, DateTimeInterface $calculationDate = null) { + $positions = $this->GetPositions($address, 'auftrag', $calculationDate); + if(empty($positions)) + return; + + $orderid = $this->app->erp->CreateAuftrag($address); + $this->app->erp->LoadAuftragStandardwerte($orderid, $address); + foreach ($positions as $pos) { + $beschreibung = $pos['beschreibung']; + $beschreibung .= "
Zeitraum: {$pos['start']} - {$pos['end']}"; + $this->app->erp->AddAuftragPositionManuell($orderid, $pos['artikel'], $pos['preis'], + $pos['menge']*$pos['cycles'], $pos['bezeichnung'], $beschreibung, $pos['waehrung'], $pos['rabatt']); + } + $this->app->erp->AuftragNeuberechnen($orderid); + $this->app->erp->BelegFreigabe('auftrag', $orderid); + } +} \ No newline at end of file diff --git a/classes/Modules/SubscriptionCycle/SubscriptionModuleInterface.php b/classes/Modules/SubscriptionCycle/SubscriptionModuleInterface.php index f30a97af..dea66b6c 100644 --- a/classes/Modules/SubscriptionCycle/SubscriptionModuleInterface.php +++ b/classes/Modules/SubscriptionCycle/SubscriptionModuleInterface.php @@ -8,36 +8,7 @@ use DateTimeInterface; interface SubscriptionModuleInterface { - /** - * @param int $customer - * @param string $documentType - * - * @return mixed - */ - public function RechnungKunde($customer, $documentType); - - /** - * @param $customer - * @param $invoiceGroupKey - * @param $key - * - * @return mixed - */ - public function AuftragImportAbo($customer, $invoiceGroupKey, $key); - - /** - * @param $customer - * @param $invoiceGroupKey - * @param $key - * - * @return mixed - */ - public function RechnungImportAbo($customer, $invoiceGroupKey, $key); - - /** - * @param string $documentType - * - * @return array|null - */ - public function GetRechnungsArray($documentType); + public function CreateInvoice(int $address, DateTimeInterface $calculationDate = null); + public function CreateOrder(int $address, DateTimeInterface $calculationDate = null); + public function GetPositions(int $address, string $documentType, DateTimeInterface $calculationDate = null): array; } diff --git a/upgrade/data/db_schema.json b/upgrade/data/db_schema.json index fbfab4fd..db865632 100644 --- a/upgrade/data/db_schema.json +++ b/upgrade/data/db_schema.json @@ -98587,6 +98587,92 @@ } ] }, + { + "name": "subscription_cycle_job", + "type": "BASE TABLE", + "columns": [ + { + "Field": "id", + "Type": "int(11)", + "Collation": null, + "Null": "NO", + "Key": "PRI", + "Default": "", + "Extra": "auto_increment", + "Privileges": "select,insert,update,references", + "Commant": "" + }, + { + "Field": "address_id", + "Type": "int(11)", + "Collation": null, + "Null": "NO", + "Key": "MUL", + "Default": "", + "Extra": "", + "Privileges": "select,insert,update,references", + "Commant": "" + }, + { + "Field": "document_type", + "Type": "varchar(32)", + "Collation": "utf8mb3_general_ci", + "Null": "NO", + "Key": "", + "Default": "", + "Extra": "", + "Privileges": "select,insert,update,references", + "Commant": "" + }, + { + "Field": "job_type", + "Type": "varchar(32)", + "Collation": "utf8mb3_general_ci", + "Null": "YES", + "Key": "", + "Default": "", + "Extra": "", + "Privileges": "select,insert,update,references", + "Commant": "" + }, + { + "Field": "printer_id", + "Type": "int(11)", + "Collation": "", + "Null": "YES", + "Key": "", + "Default": "", + "Extra": "", + "Privileges": "select,insert,update,references", + "Commant": "" + }, + { + "Field": "created_at", + "Type": "timestamp", + "Collation": "", + "Null": "NO", + "Key": "", + "Default": "current_timestamp()", + "Extra": "", + "Privileges": "select,insert,update,references", + "Commant": "" + } + ], + "keys": [ + { + "Key_name": "PRIMARY", + "columns": [ + "id" + ] + }, + { + "Key_name": "address", + "columns": [ + "address_id" + ] + } + ] + }, { "name": "supersearch_index_group", "type": "BASE TABLE", diff --git a/www/pages/content/rechnungslauf_abos.tpl b/www/pages/content/rechnungslauf_abos.tpl new file mode 100644 index 00000000..5a0a1bc9 --- /dev/null +++ b/www/pages/content/rechnungslauf_abos.tpl @@ -0,0 +1,8 @@ +
+ +
+ [TAB1] +
+
diff --git a/www/pages/content/rechnungslauf_list.tpl b/www/pages/content/rechnungslauf_list.tpl new file mode 100644 index 00000000..5df2b76a --- /dev/null +++ b/www/pages/content/rechnungslauf_list.tpl @@ -0,0 +1,36 @@ +
+ +
+ [MESSAGE_INVOICES] +
+ [TAB_INVOICES] +
+ {|Stapelverarbeitung|} +  {|alle markieren|} + +
+
+
+
+ [MESSAGE_ORDERS] +
+ [TAB_ORDERS] +
+ {|Stapelverarbeitung|} +  {|alle markieren|} + +
+
+
+
+ + diff --git a/www/pages/content/rechnungslauf_minidetail.tpl b/www/pages/content/rechnungslauf_minidetail.tpl index b3b4fd57..588464dc 100644 --- a/www/pages/content/rechnungslauf_minidetail.tpl +++ b/www/pages/content/rechnungslauf_minidetail.tpl @@ -8,7 +8,7 @@ {|Menge|} {|Einzelpreis (netto)|} {|Rabatt|} - {|UST|} + {|Zyklen|} {|Gesamtpreis (netto)|} {|Währung|} diff --git a/www/pages/rechnungslauf.php b/www/pages/rechnungslauf.php new file mode 100644 index 00000000..94a62df8 --- /dev/null +++ b/www/pages/rechnungslauf.php @@ -0,0 +1,279 @@ +'; + $menu .= ''; + $menu .= ''; + $menu .= ''; + $menu .= ''; + $menu .= ''; + $menu .= ''; + $menu .= ''; + $menu .= ''; + + $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, + '' as open, + concat('') 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 '
') 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 '
') as end, + SUM((100-aa.rabatt)/100 * aa.preis * aa.menge * + (CASE + 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 + ) + ) 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 = "
" + . "" + . "Conf->WFconf['defaulttheme']}/images/forward.svg\" border=\"0\">" + . " 
"; + + $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 + $this->app->ActionHandler('rechnungslauf', 'ActionList'); + $this->app->ActionHandler('abos', 'ActionAbos'); + $this->app->ActionHandler('minidetail', 'ActionMinidetail'); + + $this->app->ActionHandlerListen($app); + } + + public function MenuList() { + $this->app->erp->Headlines("Abolauf"); + $this->app->erp->MenuEintrag("index.php?module=rechnungslauf&action=rechnungslauf", "Übersicht"); + $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'); + $this->app->Tpl->addMessage('info', 'Die Rechnungen werden nun im Hintergrund erstellt', _var: 'MESSAGE_INVOICES'); + } + } + 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'); + $this->app->Tpl->addMessage('info', 'Die Aufträge werden nun im Hintergrund erstellt', _var: 'MESSAGE_ORDERS'); + } + } + $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 = ''; + $row .= sprintf('%s', $p['bezeichnung']); + $row .= sprintf('%s', $p['menge']); + $row .= sprintf('%s', + $this->app->erp->number_format_variable($p['preis'], 2)); + $row .= sprintf('%s', $p['rabatt']); + $row .= sprintf('%s', $p['cycles']); + $row .= sprintf('%s', + $this->app->erp->number_format_variable($p['preis']*$p['menge']*$p['cycles'], 2)); + $row .= sprintf('%s', $p['waehrung']); + $row .= ''; + $this->app->Tpl->Add('INHALT', $row); + } + $this->app->Tpl->Set('SUBHEADING', 'Kunde'); + $this->app->Tpl->Output('rechnungslauf_minidetail.tpl'); + $this->app->ExitXentral(); + } +} \ No newline at end of file