Name = 'Contract';
$this->Version = '1.0';
$this->Creator = 'Chronos';
$this->License = 'GNU/GPLv3';
$this->Description = 'Contract documents management';
$this->Dependencies = array(ModuleDocument::GetName(), ModuleSubject::GetName(), ModuleFile::GetName(), ModuleFinance::GetName());
$this->Models = array(Contract::GetClassName());
$this->DirectoryId = 0;
}
function DoStart(): void
{
$this->DirectoryId = Core::Cast($this->System)->Config['Contract']['DirectoryId'];
$this->System->RegisterPage(['smlouvy', 'generovat'], 'PageContractGenerate');
Core::Cast($this->System)->FormManager->RegisterClass('Contract', array(
'Title' => 'Smlouvy',
'Table' => 'Contract',
'Items' => array(
'DocumentLine' => array('Type' => 'TDocumentLine', 'Caption' => 'Dokladová řada', 'Default' => ''),
'BillCode' => array('Type' => 'TDocumentLineCode', 'Caption' => 'Kód', 'Default' => '', 'Null' => true),
'Subject' => array('Type' => 'TSubject', 'Caption' => 'Subjekt', 'Default' => ''),
'ValidFrom' => array('Type' => 'Date', 'Caption' => 'Platnost od', 'Default' => ''),
'ValidTo' => array('Type' => 'Date', 'Caption' => 'Platnost do', 'Default' => '', 'Null' => true),
'File' => array('Type' => 'TFile', 'Caption' => 'Soubor', 'Default' => '', 'Null' => true),
'Generate' => array('Type' => 'Boolean', 'Caption' => 'Generovat', 'Default' => ''),
'EmployeeSalaries' => array('Type' => 'TEmployeeSalaryListContract', 'Caption' => 'Výplaty zaměstnanců', 'Default' => ''),
'Customers' => array('Type' => 'TCustomerListContract', 'Caption' => 'Zákazníci', 'Default' => ''),
),
'BeforeInsert' => array($this, 'BeforeInsertContract'),
'ItemActions' => array(
array('Caption' => 'Generovat', 'URL' => '/smlouvy/generovat/?i=#RowId'),
)
));
Core::Cast($this->System)->FormManager->RegisterFormType('TContract', array(
'Type' => 'Reference',
'Table' => 'Contract',
'Id' => 'Id',
'Name' => '(SELECT `DocumentLineCode`.`Name` FROM `DocumentLineCode` WHERE `Id`=`Contract`.`BillCode`)',
'Filter' => '1',
));
}
function BeforeInsertContract(Form $Form): array
{
if (array_key_exists('Time', $Form->Values)) $Year = date("Y", $Form->Values['Time']);
else $Year = date("Y", $Form->Values['ValidFrom']);
$Form->Values['BillCode'] = ModuleDocument::Cast($this->System->GetModule('Document'))->GetNextDocumentLineNumberId($Form->Values['DocumentLine'], $Year);
return $Form->Values;
}
static function Cast(Module $Module): ModuleContract
{
if ($Module instanceof ModuleContract)
{
return $Module;
}
throw new Exception('Expected ModuleContract type but '.gettype($Module));
}
}
class PageContractGenerate extends Page
{
function __construct(System $System)
{
parent::__construct($System);
$this->Title = 'Generování smlouvy';
$this->ParentClass = 'PagePortal';
}
function GenerateContract($Where = '')
{
$DirectoryId = ModuleContract::Cast($this->System->GetModule('Contract'))->DirectoryId;
$Output = '';
$DbResult = $this->Database->query('SELECT * FROM `Contract` WHERE (`BillCode` <> "") '.
'AND (`ValidFrom` IS NOT NULL) AND (`Generate` = 1)'.$Where);
while ($Row = $DbResult->fetch_assoc())
{
if ($Row['File'] == null)
{
$this->Database->insert('File', array('Name' => '', 'Size' => 0, 'Directory' => $DirectoryId, 'Time' => 'NOW()',
'Hash' => 'SHA1(CONCAT(Id,Name,Size,Time))'));
$FileId = $this->Database->insert_id;
} else $FileId = $Row['File'];
$FileName = 'smlouva-'.$FileId.'.pdf';
$Bill = new BillContract($this->System);
$Bill->ContractId = $Row['Id'];
$FullFileName = ModuleFile::Cast($this->System->GetModule('File'))->File->GetDir($DirectoryId).$FileName;
$Bill->SaveToFile($FullFileName);
if (file_exists($FullFileName))
{
$this->Database->update('File', 'Id='.$FileId, array('Name' => $FileName, 'Size' => filesize($FullFileName), 'Hash' => 'SHA1(CONCAT(Id,Name,Size,Time))'));
$this->Database->update('Contract', 'Id='.$Row['Id'], array('File' => $FileId));
$Output .= 'Smlouva '.$Row['Id'].' vygenerována do souboru '.$FileName.'
'."\n";
} else $Output .= 'Soubor "'.$FullFileName.'" se nepodařilo uložit.';
}
return $Output;
}
function Show(): string
{
if (array_key_exists('i', $_GET) and is_numeric($_GET['i']))
{
$Output = $this->GenerateContract(' AND (Id='.($_GET['i'] * 1).')');
} else $Output = 'Missing contract id.';
return $Output;
}
}
class BillContract extends Pdf
{
public string $ContractId;
function GenerateHTML(): string
{
$this->BorderTop = '0cm';
$this->BorderLeft = '1cm';
$this->BorderRight = '1cm';
$this->BorderBottom = '0cm';
$this->FontSize = 10;
$DbResult = $this->Database->select('Subject', '*', '`Id`='.Core::Cast($this->System)->Config['Finance']['MainSubjectId']);
if ($DbResult->num_rows > 0)
{
$Supplier = $DbResult->fetch_assoc();
} else die('MainSubjectId not found in Subjects.');
$DbResult = $this->Database->query('SELECT * FROM `Contract` WHERE `Id`='.$this->ContractId);
if ($DbResult->num_rows > 0)
{
$Contract = $DbResult->fetch_array();
$DbResult = $this->Database->query('SELECT * FROM `Subject` WHERE `Id`='.$Contract['Subject']);
if ($DbResult->num_rows > 0)
{
$Subject = $DbResult->fetch_assoc();
} else die('Customer Subject not found.');
} else die('Contract not found.');
$DbResult = $this->Database->select('DocumentLineCode', '*', '`Id`='.$Contract['BillCode']);
if ($DbResult->num_rows > 0)
{
$SupplierBillCode = $DbResult->fetch_assoc();
} else die('BillCode not found.');
$ContractCode = $SupplierBillCode['Name'];
$DbResult = $this->Database->select('Member', '*', '`Subject`='.$Contract['Subject']);
if ($DbResult->num_rows > 0)
{
$Customer = $DbResult->fetch_assoc();
} else die('Customer not found.');
$PrefixMultiplier = new PrefixMultiplier();
$ServiceType = '';
$Price = 0;
$MaxSpeed = '';
$MinSpeed = '';
$DbResult = $this->Database->query('SELECT * FROM ServiceCustomerRel '.
'LEFT JOIN Service ON Service.Id=ServiceCustomerRel.Service '.
'WHERE `ServiceCustomerRel`.`Customer`='.$Customer['Id'].' ');
if ($DbResult->num_rows > 0)
{
while ($Service = $DbResult->fetch_assoc())
{
if ($ServiceType != '') $ServiceType .= ', ';
$ServiceType .= $Service['Name'];
$Price += $Service['Price'];
if ($Service['InternetSpeedMax'] != 0)
$MaxSpeed = $PrefixMultiplier->Add($Service['InternetSpeedMax'], 'bit/s');
if ($Service['InternetSpeedMin'] != 0)
$MinSpeed = $PrefixMultiplier->Add($Service['InternetSpeedMin'], 'bit/s');
}
}
$DbResult = $this->Database->query('SELECT NetworkInterface.LocalIP, NetworkInterface.MAC FROM NetworkDevice '.
'LEFT JOIN NetworkInterface ON NetworkInterface.Device=NetworkDevice.Id '.
'WHERE `NetworkDevice`.`Member`='.$Customer['Id'].' ');
if ($DbResult->num_rows > 0)
{
$NetworkInterface = $DbResult->fetch_assoc();
$IpAddress = $NetworkInterface['LocalIP'];
$MacAddress = $NetworkInterface['MAC'];
$DbResult = $this->Database->query('SELECT * FROM NetworkSubnet '.
'WHERE CompareNetworkPrefix(INET_ATON("'.$IpAddress.'"), INET_ATON(`AddressRange`), `Mask`)');
if ($DbResult->num_rows > 0)
{
$Subnet = $DbResult->fetch_assoc();
$DefaultGateway = $Subnet['Gateway'];
$NetworkAddressIPv4 = new NetworkAddressIPv4();
$NetworkAddressIPv4->Prefix = $Subnet['Mask'];
$NetworkAddressIPv4->Address = $NetworkAddressIPv4->GetNetMask();
$NetMask = $NetworkAddressIPv4->AddressToString();
} else die('Subnet not found.');
$Interface = 'Ethernet';
$PrimaryDNS = '10.145.64.8';
} else
{
$IpAddress = '';
$MacAddress = '';
$DefaultGateway = '';
$NetMask = '';
$Interface = '';
$PrimaryDNS = '';
}
$VarSymbol = $Subject['Id'];
$DbResult = $this->Database->query('SELECT FinanceBankAccount.*, CONCAT(FinanceBankAccount.Number, "/", FinanceBank.Code) AS NumberFull FROM FinanceBankAccount '.
'JOIN FinanceBank ON FinanceBank.Id=FinanceBankAccount.Bank '.
'WHERE (FinanceBankAccount.`Subject`='.Core::Cast($this->System)->Config['Finance']['MainSubjectId'].') AND (FinanceBankAccount.`Use`=1)');
if ($DbResult->num_rows > 0)
{
$SupplierBankAccount = $DbResult->fetch_assoc();
} else die('Bank account not found.');
$DbResult = $this->Database->select('FinanceBillingPeriod', '*', 'Id='.$Customer['BillingPeriod']);
if ($DbResult->num_rows > 0)
{
$BillingPeriod = $DbResult->fetch_assoc();
} else die('BillingPeriod not found.');
$PaymentPeriod = $BillingPeriod['Name'];
$BankAccount = $SupplierBankAccount['NumberFull'];
$DbResult = $this->Database->select('Member', '*', '`Subject`='.Core::Cast($this->System)->Config['Finance']['MainSubjectId']);
if ($DbResult->num_rows > 0)
{
$SupplierMember = $DbResult->fetch_assoc();
} else die('Customer not found.');
$DbResult = $this->Database->query('SELECT Contact.Value AS Phone FROM User '.
'LEFT JOIN Contact ON Contact.User=User.ID AND Contact.Category=1 '.
'WHERE User.Id='.$SupplierMember['ResponsibleUser'].' ORDER BY `Contact`.`Receive` DESC');
if ($DbResult->num_rows > 0)
{
$SupplierUser = $DbResult->fetch_assoc();
$SupplierPhone = $SupplierUser['Phone'];
} else $SupplierPhone = '';
$DbResult = $this->Database->query('SELECT Contact.Value AS Phone FROM User '.
'LEFT JOIN Contact ON Contact.User=User.ID AND Contact.Category=1 '.
'WHERE User.Id='.$Customer['ResponsibleUser'].' ORDER BY `Contact`.`Receive` DESC');
if ($DbResult->num_rows > 0)
{
$CustomerUser = $DbResult->fetch_assoc();
$CustomerPhone = $CustomerUser['Phone'];
if ($CustomerPhone == null) $CustomerPhone = '';
} else $CustomerPhone = '';
$DbResult = $this->Database->query('SELECT Email, Contact.Value AS ContactEmail FROM User '.
'LEFT JOIN Contact ON Contact.User=User.ID AND Contact.Category=4 '.
'WHERE User.Id='.$Customer['ResponsibleUser'].' ORDER BY `Contact`.`Receive` DESC');
if ($DbResult->num_rows > 0)
{
$CustomerUser = $DbResult->fetch_assoc();
$CustomerEmail = $CustomerUser['Email'];
if ($CustomerEmail == null)
{
$CustomerEmail = $CustomerUser['ContactEmail'];
if ($CustomerEmail == null) $CustomerEmail = '';
}
} else $CustomerEmail = '';
$SupplierName = $Supplier['Name'];
$SupplierStreet = $Supplier['AddressStreet'];
$SupplierTown = $Supplier['AddressTown'];
$SupplierPsc = $Supplier['AddressPSC'];
$SupplierIC = $Supplier['IC'];
if ($Supplier['PayVAT'] == 1) $SupplierDIC = 'plátce DPH';
else $SupplierDIC = 'neplátce DPH';
$Web = ''.$this->SimplifiedLink($Supplier['WWW']).'';
$CustomerName = $Subject['Name'];
$CustomerStreet = $Subject['AddressStreet'];
$CustomerTown = $Subject['AddressTown'];
$CustomerPsc = $Subject['AddressPSC'];
$CustomerIC = $Subject['IC'];
$CustomerDIC = $Subject['DIC'];
$CustomerPhone = $CustomerPhone;
$CustomerEmail = $CustomerEmail;
$SignDate = HumanDate($Contract['ValidFrom']);
$Output = '
'.
' Smlova o připojení k internetu a poskytování datových služeb '.
'Číslo: '.$ContractCode.' '.
' |
'.
'
'.
'
'.
''.
'Poskytovatel: | | Odběratel: | |
'.
''.NotBlank($SupplierName).' | | '.NotBlank($CustomerName).' | |
'.
''.NotBlank($SupplierStreet).' | | '.NotBlank($CustomerStreet).' | |
'.
''.NotBlank($SupplierTown).' | | '.NotBlank($CustomerTown).' | |
'.
''.NotBlank($SupplierPsc).' | | '.NotBlank($CustomerPsc).' | |
'.
' |
'.
'IČ: | '.NotBlank($SupplierIC).' | Telefon: | '.NotBlank($CustomerPhone).' |
'.
'DIČ: | '.NotBlank($SupplierDIC).' | E-mail: | '.NotBlank($CustomerEmail).' |
'.
'Telefon: | '.NotBlank($SupplierPhone).' | RČ/IČ: | '.NotBlank($CustomerIC).' |
'.
'Web: | '.NotBlank($Web).' | OP/DIČ: | '.NotBlank($CustomerDIC).' |
'.
'Bank. spojení: | '.NotBlank($BankAccount).' | Přípojné místo: | |
'.
'
'.
'
'.
'I. Předmět smlouvy:
'.
'Smlouva se uzavírá mezi Poskytovatelem a Odběratelem a předmětem smlouvy je poskytování datových služeb a připojení k síti internet, umožňující Odběrateli odebírat v koncovém bodě za úplatu internetovou konektivitu prostřednictvím telekomunikační sítě Poskytovatele. Odběratel se zavazuje za tyto služby Poskytovateli platit cenu ve výši a pravidelných intervalech uvedených v této smlouvě. Smlouva se sjednává na dobu neurčitou.
'.
'
'.
'II. Poskytované služby:
'.
''.
'Zvolené služby: | '.NotBlank($ServiceType).' |
'.
'
'.
'
'.
''.
'Technické specifikace služby |
'.
'Max. rychlost: | '.NotBlank($MaxSpeed).' | IP adresa: | '.NotBlank($IpAddress).' |
'.
'Min. rychlost: | '.NotBlank($MinSpeed).' | Maska podsítě: | '.NotBlank($NetMask).' |
'.
'MAC adresa: | '.NotBlank($MacAddress).' | Výchozí brána: | '.NotBlank($DefaultGateway).' |
'.
'Předávací rozhraní: | '.NotBlank($Interface).' | Primární DNS: | '.NotBlank($PrimaryDNS).' |
'.
'
'.
'
'.
'III. Cena a platební podmínky:
'.
'Poplatky a pravidelné platby budou na základě této smlouvy hrazeny Odběratelem na bankovní účet Poskytovatele bankovním převodem, nebo složenkou, v uvedené výši a s uvedenou frekvencí. Jako VS bude uvedeno přidělené číslo. V případě prodlení s platbou mohou být uplatněny sankce, či služba pozastavena, nebo zrušena (dle Ceníku a Všeobecných smluvních podmínek).
'.
''.
'Cena služeb: | '.NotBlank($Price).' Kč | Číslo účtu: | '.NotBlank($BankAccount).' |
'.
'Pronájem zařízení: | 0 Kč | Variabilní symbol: | '.NotBlank($VarSymbol).' |
'.
'Frekvence platby: | '.NotBlank($PaymentPeriod).' | | |
'.
'První platba: | | | |
'.
'Splatnost: | do 21. dne uvedeného měsíce | | |
'.
'
'.
'
'.
'IV. Závěrečná ustanovení:
'.
'Odběratel svým podpisem stvrzuje, že se seznámil a souhlasí se Všeobecnými smluvními podmínkami, aktuálním Ceníkem Poskytovatele a výše uvedenými skutečnostmi, které tvoří součást této Smlouvy. Dále stvrzuje, že souhlasí s provedením instalace a umístěním přijímacího zařízení a kabeláže a nemá proti nim námitky, příp., že vlastní veškerá příslušná povolení a souhlas s jejich umístěním. Smlouva je vyhotovena ve dvou provedeních, kdy Odběratel i Poskytovatel obdrží po jedné. Aktivace služby začíná dnem podpisu této Smlouvy. Výpovědní lhůta je 30 dnů. Případné změny této Smlouvy vyžadují formy vzájemně oběma stranami podepsaného dodatku.
'.
'
'.
''.
'Ve Zděchově | dne '.NotBlank($SignDate).' |
'.
'
'.
'
'.
''.
'odběratel | dodavatel |
'.
'
'.
''.
''.
'';
return $Output;
}
function SimplifiedLink(string $Link): string
{
if (substr($Link, 0, 8) == 'https://') $Link = substr($Link, 8);
if (substr($Link, 0, 7) == 'http://') $Link = substr($Link, 7);
return $Link;
}
}
class Contract extends Model
{
static function GetModelDesc(): ModelDesc
{
$Desc = new ModelDesc(self::GetClassName());
$Desc->AddReference('DocumentLine', DocumentLine::GetClassName());
$Desc->AddReference('BillCode', DocumentLineCode::GetClassName());
$Desc->AddReference('Subject', Subject::GetClassName());
$Desc->AddDate('ValidFrom');
$Desc->AddDate('ValidTo');
$Desc->AddReference('File', File::GetClassName());
return $Desc;
}
}