Changeset 901 for trunk/Modules/Finance


Ignore:
Timestamp:
Feb 17, 2021, 9:27:32 PM (4 years ago)
Author:
chronos
Message:
  • Added: Documents section accessible from users panel.
  • Added: Contract model moved to separate module Contract.
  • Added: New action to generate PDF from Contract.
  • Fixed: Allow users to download files only by hash instead of direct id.
  • Added: Support for SHA1 as allowed mysql function.
Location:
trunk/Modules/Finance
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Modules/Finance/Bill.php

    r888 r901  
    11<?php
    22
    3 class Bill extends Model
     3class Bill extends Pdf
    44{
    55  public int $SpecificSymbol = 1; // computer network number
    6   public bool $Checked = false;
    7 
    8   function GenerateHTML(): string
    9   {
    10     return '';
    11   }
    12 
    13   function SaveToFile(string $FileName): void
    14   {
    15     $PdfData = $this->HtmlToPdf($this->GenerateHTML());
    16     file_put_contents($FileName, $PdfData);
    17   }
    18 
    19   function HtmlToPdf(string $HtmlCode): string
    20   {
    21     $Encoding = new Encoding();
    22     if ($this->Checked == false) {
    23       if (CommandExist('htmldoc')) {
    24         $this->Checked = true;
    25       } else throw new Exception('htmldoc is not installed.');
    26     }
    27     $Output = shell_exec('echo "'.addslashes($Encoding->FromUTF8($HtmlCode)).
    28       '"|htmldoc --no-numbered --webpage --no-embedfonts --charset 8859-2 -t pdf -');
    29     return $Output;
    30   }
    316}
    327
  • trunk/Modules/Finance/Finance.php

    r900 r901  
    2121    $this->License = 'GNU/GPLv3';
    2222    $this->Description = 'Base module for finance management';
    23     $this->Dependencies = array(ModuleFile::GetName(), ModuleEmailQueue::GetName(), ModuleSubject::GetName(), ModuleDocument::GetName());
     23    $this->Dependencies = array(ModuleFile::GetName(), ModuleEmailQueue::GetName(), ModuleSubject::GetName(),
     24      ModuleDocument::GetName());
    2425    $this->Models = array(FinanceBillingPeriod::GetClassName(), FinanceVatType::GetClassName(), FinanceVat::GetClassName(),
    2526      FinanceGroup::GetClassName(), FinanceOperationGroup::GetClassName(), FinanceOperation::GetClassName(),
     
    2728      Company::GetClassName(), FinanceTreasury::GetClassName(), FinanceTreasuryCheck::GetClassName(),
    2829      Currency::GetClassName(), FinanceBank::GetClassName(), FinanceBankAccount::GetClassName(), FinanceCharge::GetClassName(),
    29       Contract::GetClassName(), FinanceInvoiceOperationRel::GetClassName());
     30      FinanceInvoiceOperationRel::GetClassName());
    3031
    3132    $this->Bill = new Bill($this->System);
     
    423424        'Name' => array('Type' => 'String', 'Caption' => 'Název', 'Default' => ''),
    424425      ),
    425     ));
    426     $this->System->FormManager->RegisterClass('Contract', array(
    427       'Title' => 'Smlouvy',
    428       'Table' => 'Contract',
    429       'Items' => array(
    430         'DocumentLine' => array('Type' => 'TDocumentLine', 'Caption' => 'Dokladová řada', 'Default' => ''),
    431         'BillCode' => array('Type' => 'TDocumentLineCode', 'Caption' => 'Kód', 'Default' => '', 'Null' => true),
    432         'Subject' => array('Type' => 'TSubject', 'Caption' => 'Subjekt', 'Default' => ''),
    433         'ValidFrom' => array('Type' => 'Date', 'Caption' => 'Platnost od', 'Default' => ''),
    434         'ValidTo' => array('Type' => 'Date', 'Caption' => 'Platnost do', 'Default' => '', 'Null' => true),
    435         'File' => array('Type' => 'TFile', 'Caption' => 'Soubor', 'Default' => '', 'Null' => true),
    436       ),
    437       'BeforeInsert' => array($this, 'BeforeInsertContract'),
    438     ));
    439     $this->System->FormManager->RegisterFormType('TContract', array(
    440       'Type' => 'Reference',
    441       'Table' => 'Contract',
    442       'Id' => 'Id',
    443       'Name' => 'BillCode',
    444       'Filter' => '1',
    445426    ));
    446427    $this->System->FormManager->RegisterFormType('TFinanceVAT', array(
     
    541522  }
    542523
    543   function DoStop(): void
    544   {
    545   }
    546 
    547524  function BeforeInsertFinanceOperation(Form $Form): array
    548525  {
     
    550527      else $Year = date("Y", $Form->Values['ValidFrom']);
    551528    $FinanceGroup = $this->Finance->GetFinanceGroupById($Form->Values['Group'], 'FinanceOperationGroup');
    552     $Form->Values['BillCode'] = $this->Finance->GetNextDocumentLineNumberId($FinanceGroup['DocumentLine'], $Year);
     529    $Form->Values['BillCode'] = ModuleDocument::Cast($this->System->GetModule('Document'))->GetNextDocumentLineNumberId($FinanceGroup['DocumentLine'], $Year);
    553530    return $Form->Values;
    554531  }
     
    576553      else $Year = date("Y", $Form->Values['ValidFrom']);
    577554    $Group = $this->Finance->GetFinanceGroupById($Form->Values['Group'], 'FinanceInvoiceGroup');
    578     $Form->Values['BillCode'] = $this->Finance->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
     555    $Form->Values['BillCode'] = ModuleDocument::Cast($this->System->GetModule('Document'))->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
    579556    return $Form->Values;
    580557  }
     
    621598  }
    622599
    623   function BeforeInsertContract(Form $Form): array
    624   {
    625     if (array_key_exists('Time', $Form->Values)) $Year = date("Y", $Form->Values['Time']);
    626       else $Year = date("Y", $Form->Values['ValidFrom']);
    627     $Form->Values['BillCode'] = $this->Finance->GetNextDocumentLineNumberId($Form->Values['DocumentLine'], $Year);
    628     return $Form->Values;
    629   }
    630 
    631600  static function Cast(Module $Module): ModuleFinance
    632601  {
  • trunk/Modules/Finance/FinanceModels.php

    r899 r901  
    7777  }
    7878
    79   function CreateFinanceYear(int $Year)
    80   {
    81     $StartTime = mktime(0, 0, 0, 1, 1, $Year);
    82     $EndTime = mktime(0, 0, 0, 12, 31, $Year);
    83     $this->Database->insert('FinanceYear', array('Year' => $Year,
    84             'DateStart' => TimeToMysqlDate($StartTime), 'DateEnd' => TimeToMysqlDate($EndTime), 'Closed' => 0));
    85           $YearId = $this->Database->insert_id;
    86 
    87     // Create DocumentLineSequence from previous
    88     $DbResult = $this->Database->select('DocumentLine', 'Id', '`Yearly` = 1');
    89     while ($DbRow = $DbResult->fetch_assoc())
     79  function GetFinanceGroupById(string $Id, string $Table): ?array
     80  {
     81    $DbResult = $this->Database->query('SELECT * FROM `'.$Table.'` WHERE `Id`= '.$Id);
     82    if ($DbResult->num_rows == 1)
    9083    {
    91             $this->Database->insert('DocumentLineSequence', array('FinanceYear' => $YearId,
    92               'NextNumber' => 1, 'YearPrefix' => 1, 'DocumentLine' => $DbRow['Id']));
    93           }
    94   }
    95 
    96   function GetFinanceYear(int $Year): array
    97   {
    98     if ($Year == 0)
    99     {
    100       // Get latest year
    101       $DbResult = $this->Database->select('FinanceYear', '*', '1 ORDER BY `Year` DESC LIMIT 1');
    102     } else $DbResult = $this->Database->select('FinanceYear', '*', '`Year`='.$Year);
    103     if ($DbResult->num_rows == 0)
    104     {
    105             if ($Year == date('Y'))
    106             {
    107                     $this->CreateFinanceYear($Year);
    108         $DbResult = $this->Database->select('FinanceYear', '*', '`Year`='.$Year);
    109             } else throw new Exception('Rok '.$Year.' nenalezen');
    110           }
    111     $FinanceYear = $DbResult->fetch_assoc();
    112     if ($FinanceYear['Closed'] == 1)
    113       throw new Exception('Rok '.$FinanceYear['Year'].' je již uzavřen. Nelze do něj přidávat položky.');
    114     return $FinanceYear;
    115   }
    116 
    117   function GetNextDocumentLineNumber(string $Id, int $FinanceYear = 0): string
    118   {
    119           $FinanceYear = $this->GetFinanceYear($FinanceYear);
    120 
    121     $DbResult = $this->Database->query('SELECT `Shortcut`, `Id` FROM `DocumentLine` WHERE `Id`='.$Id);
    122     $DocumentLine = $DbResult->fetch_assoc();
    123 
    124     $DbResult = $this->Database->query('SELECT * FROM `DocumentLineSequence` WHERE '.
    125       '`DocumentLine`='.$Id.' AND `FinanceYear`='.$FinanceYear['Id']);
    126     $Sequence = $DbResult->fetch_assoc();
    127 
    128     if ($Sequence['YearPrefix'] == 1)
    129     {
    130       $Result = $DocumentLine['Shortcut'].$Sequence['NextNumber'].'/'.$FinanceYear['Year'];
    131     } else $Result = $DocumentLine['Shortcut'].$Sequence['NextNumber'];
    132 
    133     $this->Database->query('UPDATE `DocumentLineSequence` SET `NextNumber` = `NextNumber` + 1 '.
    134       'WHERE (`DocumentLine`='.$Id.') AND (`FinanceYear`='.$FinanceYear['Id'].')');
    135     return $Result;
    136   }
    137 
    138   function GetNextDocumentLineNumberId(string $Id, int $FinanceYear = 0): int
    139   {
    140     $Code = $this->GetNextDocumentLineNumber($Id, $FinanceYear);
    141     $this->Database->insert('DocumentLineCode', array('DocumentLine' => $Id, 'Name' => $Code));
    142     return $this->Database->insert_id;
    143   }
    144 
    145   function GetFinanceGroupById(string $Id, string $Table): ?array
    146   {
    147     $DbResult = $this->Database->query('SELECT * FROM `'.$Table.'` WHERE `Id`= '.$Id);
    148     if ($DbResult->num_rows == 1) {
    14984      $Group = $DbResult->fetch_assoc();
    15085      return $Group;
     
    443378}
    444379
    445 class Contract extends Model
    446 {
    447   static function GetModelDesc(): ModelDesc
    448   {
    449     $Desc = new ModelDesc(self::GetClassName());
    450     $Desc->AddReference('DocumentLine', DocumentLine::GetClassName());
    451     $Desc->AddReference('BillCode', DocumentLineCode::GetClassName());
    452     $Desc->AddReference('Subject', Subject::GetClassName());
    453     $Desc->AddDate('ValidFrom');
    454     $Desc->AddDate('ValidTo');
    455     $Desc->AddReference('File', File::GetClassName());
    456     return $Desc;
    457   }
    458 }
    459 
    460380class FinanceBillingPeriod extends Model
    461381{
  • trunk/Modules/Finance/Import.php

    r888 r901  
    131131  {
    132132    $Year = date('Y', $Time);
    133     $BillCode = ModuleFinance::Cast($this->System->GetModule('Finance'))->Finance->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
     133    $BillCode = ModuleDocument::Cast($this->System->GetModule('Document'))->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
    134134    // TODO: Fixed BankAccount=1, allow to select bank account for import
    135135    $this->Database->insert('FinanceOperation', array('Text' => $Text,
  • trunk/Modules/Finance/Manage.php

    r887 r901  
    135135
    136136    $Year = date('Y', $TimeCreation);
    137     $BillCode = $Finance->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
     137    $BillCode = ModuleDocument::Cast($this->System->GetModule('Document'))->GetNextDocumentLineNumberId($Group['DocumentLine'], $Year);
    138138    $SumValue = 0;
    139139    foreach ($Items as $Item) {
     
    377377      $Title = 'Pravidelné vyúčtování služeb';
    378378      $Content = 'Vyúčtovaní zákazníka <strong>'.$Subject['Name'].'</strong> zastoupeného uživatelem <strong>'.
    379         $User['Name'].'</strong> ke dni <strong>'.$this->System->HumanDate(time()).'</strong>.<br/><br/>'."\n".
     379        $User['Name'].'</strong> ke dni <strong>'.Core::Cast($this->System)->HumanDate(time()).'</strong>.<br/><br/>'."\n".
    380380        'Vaše aktuální služby: ';
    381381      $DbResult = $this->Database->query('SELECT GROUP_CONCAT(`Service`.`Name`) AS `Name` FROM `ServiceCustomerRel` LEFT JOIN `Service` '.
     
    441441      if (file_exists($FullFileName))
    442442      {
    443         $this->Database->update('File', 'Id='.$FileId, array('Name' => $FileName, 'Size' => filesize($FullFileName)));
     443        $this->Database->update('File', 'Id='.$FileId, array('Name' => $FileName, 'Size' => filesize($FullFileName), 'Hash' => 'SHA1(CONCAT(Id,Name,Size,Time))'));
    444444        $this->Database->update('FinanceInvoice', 'Id='.$Row['Id'], array('File' => $FileId));
    445445        $Output .= 'Faktura '.$Row['Id'].' vygenerována do souboru '.$FileName.'<br/>'."\n";
     
    472472      if (file_exists($FullFileName))
    473473      {
    474         $this->Database->update('File', 'Id='.$FileId, array('Name' => $FileName, 'Size' => filesize($FullFileName)));
     474        $this->Database->update('File', 'Id='.$FileId, array('Name' => $FileName, 'Size' => filesize($FullFileName), 'Hash' => 'SHA1(CONCAT(Id,Name,Size,Time))'));
    475475        $this->Database->update('FinanceOperation', 'Id='.$Row['Id'], array('File' => $FileId));
    476476        $Output .= 'Doklad pro platbu '.$Row['Id'].' vygenerován do souboru '.$FileName.'<br/>'."\n";
  • trunk/Modules/Finance/UserState.php

    r888 r901  
    1111  }
    1212
    13   function ShowFinanceOperation(int $Subject): string
     13  function ShowFinanceOperation(int $SubjectId): string
    1414  {
    15     $UserOperationTableQuery = '((SELECT `Text`, `Time`, `Value`, `File`, `BillCode`, NULL AS `PeriodFrom`, NULL AS `PeriodTo`, `DocumentLineCode`.`Name` AS `BillName` '.
     15    $UserOperationTableQuery = '((SELECT `Text`, `FinanceOperation`.`Time`, `Value`, `File`.`Hash` AS `FileHash`, `BillCode`, NULL AS `PeriodFrom`, NULL AS `PeriodTo`, `DocumentLineCode`.`Name` AS `BillName` '.
    1616      'FROM `FinanceOperation` '.
    1717      'LEFT JOIN `DocumentLineCode` ON `DocumentLineCode`.`Id`=`FinanceOperation`.`BillCode` '.
    18       'WHERE (`Subject`='.$Subject['Id'].') '.
     18      'LEFT JOIN `File` ON `File`.`Id`=`FinanceOperation`.`File` '.
     19      'WHERE (`Subject`='.$SubjectId.') '.
    1920      ') UNION ALL '.
    2021      '(SELECT (SELECT GROUP_CONCAT(`Description` SEPARATOR ",") FROM `FinanceInvoiceItem` WHERE `FinanceInvoice`=`FinanceInvoice`.`Id`) AS `Text`, '.
    21       '`Time`, -`Value`, `File`, `BillCode`, `PeriodFrom`, `PeriodTo`, `DocumentLineCode`.`Name` AS `BillName` FROM `FinanceInvoice` '.
     22      '`FinanceInvoice`.`Time`, -`Value`, `File`.`Hash` AS `FileHash`, `BillCode`, `PeriodFrom`, `PeriodTo`, `DocumentLineCode`.`Name` AS `BillName` '.
     23      'FROM `FinanceInvoice` '.
    2224      'LEFT JOIN `DocumentLineCode` ON `DocumentLineCode`.`Id`=`FinanceInvoice`.`BillCode` '.
    23       'WHERE (`Subject`='.$Subject['Id'].') AND (`VisibleToUser` = 1)))';
     25      'LEFT JOIN `File` ON `File`.`Id`=`FinanceInvoice`.`File` '.
     26      'WHERE (`Subject`='.$SubjectId.') AND (`VisibleToUser` = 1)))';
    2427
    2528    $Output = '<div style="text-align:center">Výpis finančních operací</div>';
     
    5659      if ($Row['Value'] > 0) $Row['Value'] = '+'.$Row['Value'];
    5760      if ($Row['BillName'] == '') $Row['BillName'] = 'PDF';
    58       if ($Row['File'] > 0) $Invoice = '<a href="'.$this->System->Link('/file?id='.$Row['File']).'">'.$Row['BillName'].'</a>';
     61      if ($Row['FileHash'] != '') $Invoice = '<a href="'.$this->System->Link('/file?h='.$Row['FileHash']).'">'.$Row['BillName'].'</a>';
    5962        else $Invoice = NotBlank($Row['BillName']);
    6063      if ($Row['PeriodFrom'] != '') $Period = HumanDate($Row['PeriodFrom']).' - '.HumanDate($Row['PeriodTo']);
     
    102105    } else return $this->SystemMessage('Položka nenalezena', 'Zákazník nenalezen');
    103106
    104 
    105107    // Load subject info
    106108    $DbResult = $this->Database->query('SELECT * FROM `Subject` WHERE `Id`='.$Customer['Subject']);
     
    109111      $Subject = $DbResult->fetch_assoc();
    110112    } else return $this->SystemMessage('Položka nenalezena', 'Subjekt nenalezen');
    111 
    112113
    113114    $Output = '<table width="100%" border="0" cellspacing="0" cellpadding="3"><tr><td valign="top">';
     
    124125
    125126    // Tabulka operaci
    126     $Output .= $this->ShowFinanceOperation($Subject);
     127    $Output .= $this->ShowFinanceOperation($Subject['Id']);
    127128
    128129    $Output .= '</td><td valign="top">';
Note: See TracChangeset for help on using the changeset viewer.