<?php

class ModuleSubject extends Module
{
  function __construct(System $System)
  {
    parent::__construct($System);
    $this->Name = 'Subject';
    $this->Version = '1.0';
    $this->Creator = 'Chronos';
    $this->License = 'GNU/GPLv3';
    $this->Description = 'Subject management';
    $this->Dependencies = array(ModuleUser::GetName(), ModuleMap::GetName());
    $this->Models = array(Subject::GetClassName(), ContactCategory::GetClassName(),
      Contact::GetClassName());
  }

  function DoStart(): void
  {
    $this->System->FormManager->RegisterClass('Subject', array(
      'Title' => 'Subjekty',
      'Table' => 'Subject',
      'DefaultSortColumn' => 'Name',
      'Items' => array(
        'Id' => array('Type' => 'Integer', 'Caption' => 'Identifikace', 'Default' => '', 'ReadOnly' => true),
        'Name' => array('Type' => 'String', 'Caption' => 'Celé jméno', 'Default' => '', 'Required' => true),
        'AddressStreet' => array('Type' => 'String', 'Caption' => 'Ulice', 'Default' => ''),
        'AddressTown' => array('Type' => 'String', 'Caption' => 'Město', 'Default' => ''),
        'AddressPSC' => array('Type' => 'Integer', 'Caption' => 'PSČ', 'Default' => '', 'Required' => true),
        'AddressCountry' => array('Type' => 'TCountry', 'Caption' => 'Země', 'Default' => ''),
        'IC' => array('Type' => 'String', 'Caption' => 'IČ', 'Default' => ''),
        'DIC' => array('Type' => 'String', 'Caption' => 'DIČ', 'Default' => ''),
        'PayVAT' => array('Type' => 'Boolean', 'Caption' => 'Plátce DPH', 'Default' => 0),
        'MapPosition' => array('Type' => 'TMapPosition', 'Caption' => 'Pozice na mapě', 'Default' => '', 'Null' => true),
        'WWW' => array('Type' => 'Hyperlink', 'Caption' => 'WWW', 'Default' => ''),
        'Note' => array('Type' => 'String', 'Caption' => 'Poznámka', 'Default' => ''),
        'Customer' => array('Type' => 'TMemberListSubject', 'Caption' => 'Členové', 'Default' => ''),
        'Operations' => array('Type' => 'TFinanceOperationListSubject', 'Caption' => 'Platby', 'Default' => ''),
        'Invoices' => array('Type' => 'TFinanceInvoiceListSubject', 'Caption' => 'Faktury', 'Default' => ''),
        'Payment' => array('Type' => 'Float', 'Caption' => 'Placení', 'Default' => '',
          'ReadOnly' => true, 'Suffix' => 'Kč', 'SQL' => 'ROUND(IFNULL((SELECT SUM(`FinanceOperation`.`Value`) FROM `FinanceOperation` '.
          'WHERE `FinanceOperation`.`Subject`=#Id), 0) - IFNULL((SELECT SUM(`FinanceInvoice`.`Value`) FROM `FinanceInvoice` '.
          'WHERE `FinanceInvoice`.`Subject`=#Id), 0))'),
        'BankAccounts' => array('Type' => 'TFinanceBankAccountListSubject', 'Caption' => 'Bankovní účty', 'Default' => ''),
        'Contracts' => array('Type' => 'TContractListSubject', 'Caption' => 'Smlouvy', 'Default' => ''),
        'Contacts' => array('Type' => 'TContactListSubject', 'Caption' => 'Kontakty', 'Default' => ''),
      ),
    ));
    $this->System->FormManager->RegisterFormType('TFinanceBankAccountListSubject', array(
      'Type' => 'ManyToOne',
      'Table' => 'FinanceBankAccount',
      'Id' => 'Id',
      'Ref' => 'Subject',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TContractListSubject', array(
      'Type' => 'ManyToOne',
      'Table' => 'Contract',
      'Id' => 'Id',
      'Ref' => 'Subject',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TContactListSubject', array(
      'Type' => 'ManyToOne',
      'Table' => 'Contact',
      'Id' => 'Id',
      'Ref' => 'Subject',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterClass('SubjectReport', array(
      'Title' => 'Přehled subjektů',
      'Table' => 'SubjectReport',
      'DefaultSortColumn' => 'Id',
      'SQL' => '(SELECT Id FROM Subject)',
      'Items' => array(
        'Id' => array('Type' => 'TSubject', 'Caption' => 'Subjekt', 'Default' => '', 'ReadOnly' => true),
        'Income' => array('Type' => 'Integer', 'Caption' => 'Příjmy', 'Default' => '0', 'Suffix' => 'Kč', 'ReadOnly' => true,
          'SQL' => '(SELECT ROUND(SUM(`FinanceOperation`.`Value`)) FROM `FinanceOperation` '.
            'LEFT JOIN `FinanceOperationGroup` ON `FinanceOperationGroup`.`Id`=`FinanceOperation`.`Group` '.
            'WHERE (`FinanceOperation`.`Subject` = TX.`Id`) '.
            'AND (`FinanceOperationGroup`.`ValueSign` = 1))'),
        'Spending' => array('Type' => 'Integer', 'Caption' => 'Výdaje', 'Default' => '0', 'Suffix' => 'Kč', 'ReadOnly' => true,
          'SQL' => '(SELECT -ROUND(SUM(`FinanceOperation`.`Value`)) FROM `FinanceOperation` '.
            'LEFT JOIN `FinanceOperationGroup` ON `FinanceOperationGroup`.`Id`=`FinanceOperation`.`Group` '.
            'WHERE (`FinanceOperation`.`Subject` = TX.`Id`) '.
            'AND (`FinanceOperationGroup`.`ValueSign` = -1))'),
        'OperationBalance' => array('Type' => 'Integer', 'Caption' => 'Zisk', 'Default' => '0', 'Suffix' => 'Kč', 'ReadOnly' => true,
          'SQL' => '(SELECT ROUND(SUM(`FinanceOperation`.`Value`)) FROM `FinanceOperation` WHERE (`FinanceOperation`.`Subject` = TX.`Id`) '.
          ')'),
      ),
    ));
    $this->System->FormManager->RegisterFormType('TContactCategory', array(
      'Type' => 'Reference',
      'Table' => 'ContactCategory',
      'Id' => 'Id',
      'Name' => 'Name',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TContactListCategory', array(
      'Type' => 'ManyToOne',
      'Table' => 'Contact',
      'Id' => 'Id',
      'Ref' => 'Category',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TContactListUser', array(
      'Type' => 'ManyToOne',
      'Table' => 'Contact',
      'Id' => 'Id',
      'Ref' => 'User',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterClass('Contact', array(
      'Title' => 'Kontakty',
      'Table' => 'Contact',
      'Items' => array(
        'Category' => array('Type' => 'TContactCategory', 'Caption' => 'Druh', 'Default' => ''),
        'Value' => array('Type' => 'String', 'Caption' => 'Hodnota', 'Default' => ''),
        'User' => array('Type' => 'TUser', 'Caption' => 'Uživatel', 'Default' => '', 'Null' => true),
        'Subject' => array('Type' => 'TSubject', 'Caption' => 'Subject', 'Default' => '', 'Null' => true),
        'Description' => array('Type' => 'String', 'Caption' => 'Popis', 'Default' => ''),
        'Receive' => array('Type' => 'Boolean', 'Caption' => 'Přijímat zprávy', 'Default' => '0'),
      ),
    ));
    $this->System->FormManager->RegisterClass('ContactCategory', array(
      'Title' => 'Druh kontaktu',
      'Table' => 'ContactCategory',
      'Items' => array(
        'Name' => array('Type' => 'String', 'Caption' => 'Jméno', 'Default' => ''),
        'Items' => array('Type' => 'TContactListCategory', 'Caption' => 'Kontakty'),
      ),
    ));
    $this->System->FormManager->RegisterFormType('TContact', array(
      'Type' => 'Reference',
      'Table' => 'Contact',
      'Id' => 'Id',
      'Name' => 'Value',
      'Filter' => '1',
    ));
    $this->System->FormManager->RegisterFormType('TSubject', array(
      'Type' => 'Reference',
      'Table' => 'Subject',
      'Id' => 'Id',
      'Name' => 'Name',
      'Filter' => '1',
    ));
    ModuleIS::Cast(Core::Cast($this->System)->GetModule('IS'))->RegisterDashboardItem('Subject',
      array($this, 'ShowDashboardItem'));
  }

  function ShowDashboardItem(): string
  {
    $DbResult = $this->Database->select('Subject', 'COUNT(*)', '1');
    $DbRow = $DbResult->fetch_row();
    $Output = 'Subjektů: <a href="'.$this->System->Link('/is/?a=list&amp;t=Subject').'">'.$DbRow['0'].'</a><br/>';
    return $Output;
  }
}

class Subject extends Model
{
  static function GetModelDesc(): ModelDesc
  {
    $Desc = new ModelDesc(self::GetClassName());
    $Desc->AddString('Name');
    $Desc->AddString('AddressStreet');
    $Desc->AddString('AddressTown');
    $Desc->AddString('AddressPSC');
    $Desc->AddReference('AddressCountry', Country::GetClassName(), true);
    $Desc->AddString('IC');
    $Desc->AddString('DIC');
    $Desc->AddBoolean('PayVAT');
    $Desc->AddReference('MapPosition', MapPosition::GetClassName(), true);
    $Desc->AddString('WWW');
    $Desc->AddString('Note');
    return $Desc;
  }
}

class Contact extends Model
{
  static function GetModelDesc(): ModelDesc
  {
    $Desc = new ModelDesc(self::GetClassName());
    $Desc->AddReference('Category', ContactCategory::GetClassName(), true);
    $Desc->AddString('Value');
    $Desc->AddReference('Subject', Subject::GetClassName(), true);
    $Desc->AddReference('User', User::GetClassName(), true);
    $Desc->AddString('Description');
    $Desc->AddBoolean('Receive');
    return $Desc;
  }
}

class ContactCategory extends Model
{
  static function GetModelDesc(): ModelDesc
  {
    $Desc = new ModelDesc(self::GetClassName());
    $Desc->AddString('Name');
    return $Desc;
  }
}
