This commit is contained in:
Beppe 2021-04-20 18:26:24 +02:00
commit c372b7a326
17 changed files with 601 additions and 13 deletions

View File

@ -37,6 +37,8 @@ Il formato utilizzato è basato sulle linee guida di [Keep a Changelog](http://k
### Aggiunto (Added)
- Nuovo *Sconto finale* per gli **Ordini**, **Preventivi**, **DDT** e **Contratti**, influenza il valore *Netto a pagare* del documento.
- Nuovo filtro in attività per mostrare al tecnico solo le attività assegnate.
- Nuovo filtro in contratti per mostrare al cliente solo i contratti collegati.
- Nuovo pulsante **Duplica Template** per copiare un template già esistente.
## 2.4.22

527
modules/banche/src/IBAN.php Normal file
View File

@ -0,0 +1,527 @@
<?php
namespace Modules\Banche;
use UnexpectedValueException;
/**
* Format:
* b = National bank code (Codice ABI)
* s = Bank/branch code (sort code, or CAB Codice d'Avviamento Bancario)
* c = Account number
* d = Account type
* i = National identification number
* k = IBAN check digits
* x = National check digits (CIN).
*/
class IBAN
{
public static $countries = [
'AL' => [
'length' => 28,
'pattern' => '8n 16c',
'structure' => 'ALkk bbbs sssx cccc cccc cccc cccc',
],
'AD' => [
'length' => 24,
'pattern' => '8n 12c',
'structure' => 'ADkk bbbb ssss cccc cccc cccc',
],
'AT' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'ATkk bbbb bccc cccc cccc',
],
'AZ' => [
'length' => 28,
'pattern' => '4c 20n',
'structure' => 'AZkk bbbb cccc cccc cccc cccc cccc',
],
'BH' => [
'length' => 22,
'pattern' => '4a 14c',
'structure' => 'BHkk bbbb cccc cccc cccc cc',
],
'BE' => [
'length' => 16,
'pattern' => '12n',
'structure' => 'BEkk bbbc cccc ccxx',
],
'BA' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'BA39 bbbs sscc cccc ccxx',
],
'BR' => [
'length' => 29,
'pattern' => '23n 1a 1c',
'structure' => 'BR39 bbbb bbbb ssss sccc cccc cccc c',
],
'BG' => [
'length' => 22,
'pattern' => '4a 6n 8c',
'structure' => 'BGkk bbbb ssss ddcc cccc cc',
],
'CR' => [
'length' => 21,
'pattern' => '17n',
'structure' => 'CRkk bbbc cccc cccc cccc c',
],
'HR' => [
'length' => 21,
'pattern' => '17n',
'structure' => 'HRkk bbbb bbbc cccc cccc c',
],
'CY' => [
'length' => 28,
'pattern' => '8n 16c',
'structure' => 'CYkk bbbs ssss cccc cccc cccc cccc',
],
'CZ' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'CZkk bbbb ssss sscc cccc cccc',
],
'DK' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'DKkk bbbb cccc cccc cc',
],
'DO' => [
'length' => 28,
'pattern' => '4a 20n',
'structure' => 'DOkk bbbb cccc cccc cccc cccc cccc',
],
'EE' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'EEkk bbss cccc cccc cccx',
],
'FO' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'FOkk bbbb cccc cccc cx',
],
'FI' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'FIkk bbbb bbcc cccc cx',
],
'FR' => [
'length' => 27,
'pattern' => '10n 11c 2n',
'structure' => 'FRkk bbbb bggg ggcc cccc cccc cxx',
],
'GE' => [
'length' => 22,
'pattern' => '2c 16n',
'structure' => 'GEkk bbcc cccc cccc cccc cc',
],
'DE' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'DEkk bbbb bbbb cccc cccc cc',
],
'GI' => [
'length' => 23,
'pattern' => '4a 15c',
'structure' => 'GIkk bbbb cccc cccc cccc ccc',
],
'GR' => [
'length' => 27,
'pattern' => '7n 16c',
'structure' => 'GRkk bbbs sssc cccc cccc cccc ccc',
],
'GL' => [
'length' => 18,
'pattern' => '14n',
'structure' => 'GLkk bbbb cccc cccc cc',
],
'GT' => [
'length' => 28,
'pattern' => '4c 20c',
'structure' => 'GTkk bbbb cccc cccc cccc cccc cccc',
],
'HU' => [
'length' => 28,
'pattern' => '24n',
'structure' => 'HUkk bbbs sssk cccc cccc cccc cccx',
],
'IS' => [
'length' => 26,
'pattern' => '22n',
'structure' => 'ISkk bbbb sscc cccc iiii iiii ii',
],
'IE' => [
'length' => 22,
'pattern' => '4c 14n',
'structure' => 'IEkk aaaa bbbb bbcc cccc cc',
],
'IL' => [
'length' => 23,
'pattern' => '19n',
'structure' => 'ILkk bbbn nncc cccc cccc ccc',
],
'IT' => [
'length' => 27,
'pattern' => '1a 10n 12c',
'structure' => 'ITkk xbbb bbss sssc cccc cccc ccc',
],
'KZ' => [
'length' => 20,
'pattern' => '3n 13c',
'structure' => 'KZkk bbbc cccc cccc cccc',
],
'KW' => [
'length' => 30,
'pattern' => '4a 22c',
'structure' => 'KWkk bbbb cccc cccc cccc cccc cccc cc',
],
'LV' => [
'length' => 21,
'pattern' => '4a 13c',
'structure' => 'LVkk bbbb cccc cccc cccc c',
],
'LB' => [
'length' => 28,
'pattern' => '4n 20c',
'structure' => 'LBkk bbbb cccc cccc cccc cccc cccc',
],
'LI' => [
'length' => 21,
'pattern' => '5n 12c',
'structure' => 'LIkk bbbb bccc cccc cccc c',
],
'LT' => [
'length' => 20,
'pattern' => '16n',
'structure' => 'LTkk bbbb bccc cccc cccc',
],
'LU' => [
'length' => 20,
'pattern' => '3n 13c',
'structure' => 'LUkk bbbc cccc cccc cccc',
],
'MK' => [
'length' => 19,
'pattern' => '3n 10c 2n',
'structure' => 'MK07 bbbc cccc cccc cxx',
],
'MT' => [
'length' => 31,
'pattern' => '4a 5n 18c',
'structure' => 'MTkk bbbb ssss sccc cccc cccc cccc ccc',
],
'MR' => [
'length' => 27,
'pattern' => '23n',
'structure' => 'MRkk bbbb bsss sscc cccc cccc cxx',
],
'MU' => [
'length' => 30,
'pattern' => '4a 19n 3a',
'structure' => 'MUkk bbbb bbss cccc cccc cccc cccc cc',
],
'MC' => [
'length' => 27,
'pattern' => '10n 11c 2n',
'structure' => 'MCkk bbbb bsss sscc cccc cccc cxx',
],
'MD' => [
'length' => 24,
'pattern' => '2c 18n',
'structure' => 'MDkk bbcc cccc cccc cccc cccc',
],
'ME' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'ME25 bbbc cccc cccc cccc xx',
],
'NL' => [
'length' => 18,
'pattern' => '4a 10n',
'structure' => 'NLkk bbbb cccc cccc cc',
],
'NO' => [
'length' => 15,
'pattern' => '11n',
'structure' => 'NOkk bbbb cccc ccx',
],
'PK' => [
'length' => 24,
'pattern' => '4c 16n',
'structure' => 'PKkk bbbb cccc cccc cccc cccc',
],
'PS' => [
'length' => 29,
'pattern' => '4c 21n',
'structure' => 'PSkk bbbb zzzz zzzz zccc cccc cccc c',
],
'PL' => [
'length' => 28,
'pattern' => '24n',
'structure' => 'PLkk bbbs sssx cccc cccc cccc cccc',
],
'PT' => [
'length' => 25,
'pattern' => '21n',
'structure' => 'PT50 bbbb ssss cccc cccc cccx x',
],
'RO' => [
'length' => 24,
'pattern' => '4a 16c',
'structure' => 'ROkk bbbb cccc cccc cccc cccc',
],
'SM' => [
'length' => 27,
'pattern' => '1a 10n 12c',
'structure' => 'SMkk xbbb bbss sssc cccc cccc ccc',
],
'SA' => [
'length' => 24,
'pattern' => '2n 18c',
'structure' => 'SAkk bbcc cccc cccc cccc cccc',
],
'RS' => [
'length' => 22,
'pattern' => '18n',
'structure' => 'RSkk bbbc cccc cccc cccc aa',
],
'SK' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'SKkk bbbb ssss sscc cccc cccc',
],
'SI' => [
'length' => 19,
'pattern' => '15n',
'structure' => 'SI56 bbss sccc cccc cxx',
],
'ES' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'ESkk bbbb ssss xxcc cccc cccc',
],
'SE' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'SEkk bbbc cccc cccc cccc cccc',
],
'CH' => [
'length' => 21,
'pattern' => '5n 12c',
'structure' => 'CHkk bbbb bccc cccc cccc c',
],
'TN' => [
'length' => 24,
'pattern' => '20n',
'structure' => 'TNkk bbss sccc cccc cccc cccc',
],
'TR' => [
'length' => 26,
'pattern' => '5n 17c',
'structure' => 'TRkk bbbb b0cc cccc cccc cccc cc',
],
'AE' => [
'length' => 23,
'pattern' => '3n 16n',
'structure' => 'AEkk bbbc cccc cccc cccc ccc',
],
'GB' => [
'length' => 22,
'pattern' => '4a 14n',
'structure' => 'GBkk bbbb ssss sscc cccc cc',
],
'VG' => [
'length' => 24,
'pattern' => '4c 16n',
'structure' => 'VGkk bbbb cccc cccc cccc cccc',
],
];
protected static $parsers = [
'b' => 'bank_code',
's' => 'branch_code',
'c' => 'account_number',
'd' => 'account_type',
'i' => 'id',
'k' => 'check_digits',
'x' => 'national_check_digits',
];
/**
* @var string
*/
protected $iban;
/**
* @var string
*/
protected $nation;
/**
* @var string
*/
protected $bank_code;
/**
* @var string
*/
protected $branch_code;
/**
* @var string
*/
protected $account_number;
/**
* @var string
*/
protected $account_type;
/**
* @var string
*/
protected $id;
/**
* @var string
*/
protected $check_digits;
/**
* @var string
*/
protected $national_check_digits;
public function __construct($iban)
{
$iban = str_replace(' ', '', $iban);
$this->iban = $iban;
$this->nation = $nation = substr($iban, 0, 2);
$info = self::$countries[$nation];
$structure = $info['structure'];
$structure = str_replace(' ', '', $structure);
$regex = $nation;
$keys = array_keys(self::$parsers);
$length = strlen($this->iban);
$current = strlen($nation);
while ($current <= $length) {
$char = $structure[$current];
if (in_array($char, $keys)) {
$count = substr_count($structure, $char);
$regex .= '(?<'.self::$parsers[$char].'>[A-Z0-9]{'.$count.'})';
$current += $count;
} else {
$regex .= $char;
++$current;
}
}
preg_match_all('/^'.$regex.'/', $iban, $matches);
$matches = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
foreach ($matches as $key => $value) {
if (empty($value[0])) {
throw new UnexpectedValueException('Invalid '.$key.' for format '.$regex);
}
$this->{$key} = $value[0];
}
}
public static function generate($contents = [])
{
$nation = $contents['nation'];
$info = self::$countries[$nation];
$structure = $info['structure'];
$structure = str_replace(' ', '', $structure);
$keys = array_keys(self::$parsers);
$length = strlen($structure);
$current = strlen($nation);
$result = $nation;
while ($current <= $length) {
$char = $structure[$current];
if (in_array($char, $keys)) {
$count = substr_count($structure, $char);
$result .= str_pad($contents[self::$parsers[$char]], $count, STR_PAD_LEFT);
$current += $count;
} else {
$result .= $char;
++$current;
}
}
return new self($result);
}
/**
* @return string
*/
public function getIban()
{
return $this->iban;
}
/**
* @return string
*/
public function getNation()
{
return $this->nation;
}
/**
* @return string
*/
public function getBankCode()
{
return $this->bank_code;
}
/**
* @return string
*/
public function getBranchCode()
{
return $this->branch_code;
}
/**
* @return string
*/
public function getAccountNumber()
{
return $this->account_number;
}
/**
* @return string
*/
public function getAccountType()
{
return $this->account_type;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getCheckDigits()
{
return $this->check_digits;
}
/**
* @return string
*/
public function getNationalCheckDigits()
{
return $this->national_check_digits;
}
}

View File

@ -475,6 +475,7 @@ $riga = $contratto->getRiga($type, $id_riga);
$contratto->descrizione = $documento->descrizione;
$contratto->esclusioni = $documento->esclusioni;
$contratto->idreferente = $documento->idreferente;
$contratto->save();

View File

@ -326,6 +326,7 @@ switch (post('op')) {
$ddt->idsede_destinazione = $id_sede;
$ddt->idcausalet = post('id_causale_trasporto');
$ddt->idreferente = $documento->idreferente;
$ddt->save();

View File

@ -58,5 +58,18 @@ switch (post('op')) {
flash()->info(tr('Template delle email eliminato!'));
break;
case 'copy':
$dbo->query('CREATE TEMPORARY TABLE tmp SELECT * FROM em_templates WHERE id= '.prepare($id_record));
$dbo->query('ALTER TABLE tmp DROP id');
$dbo->query('INSERT INTO em_templates SELECT NULL,tmp. * FROM tmp');
$id_record = $dbo->lastInsertedID();
$dbo->query('DROP TEMPORARY TABLE tmp');
$dbo->query('UPDATE em_templates SET name = CONCAT (name, " (copia)") WHERE id = '.prepare($id_record));
flash()->info(tr('Template duplicato correttamente!'));
break;
}

View File

@ -0,0 +1,31 @@
<?php
/*
* OpenSTAManager: il software gestionale open source per l'assistenza tecnica e la fatturazione
* Copyright (C) DevCode s.r.l.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
include_once __DIR__.'/../../core.php';
echo'
<button type="button" class="btn btn-primary" onclick="if( confirm(\'Duplicare questo template?\') ){ $(\'#copia-template\').submit(); }"> <i class="fa fa-copy"></i> '.tr('Duplica template').'</button>';
// Duplica template
echo '
<form action="" method="post" id="copia-template">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="copy">
</form>';

View File

@ -697,6 +697,7 @@ switch (post('op')) {
$fattura->idsede_destinazione = $documento->idsede;
$fattura->id_ritenuta_contributi = post('id_ritenuta_contributi') ?: null;
$fattura->idreferente = $documento->idreferente;
$fattura->save();

View File

@ -68,7 +68,8 @@ $totale_scadenze = $dbo->fetchOne('SELECT SUM(da_pagare - pagato) AS differenza,
if (!empty($record['is_fiscale'])) {
// Aggiunta insoluto
$registrazione_insoluto = 0;
if (!empty($record['riba']) && $dir == 'entrata' && in_array($record['stato'], ['Emessa', 'Parzialmente pagato', 'Pagato'])) {
$pagamento = $fattura->pagamento;
if ($pagamento->isRiBa() && $dir == 'entrata' && in_array($record['stato'], ['Emessa', 'Parzialmente pagato', 'Pagato'])) {
$registrazione_insoluto = 1;
}

View File

@ -46,7 +46,6 @@ if (isset($id_record)) {
co_documenti.split_payment AS split_payment,
co_statidocumento.descrizione AS `stato`,
co_tipidocumento.descrizione AS `descrizione_tipo`,
co_pagamenti.riba AS `riba`,
(SELECT is_fiscale FROM zz_segments WHERE id = id_segment) AS is_fiscale,
(SELECT descrizione FROM co_ritenutaacconto WHERE id=idritenutaacconto) AS ritenutaacconto_desc,
(SELECT descrizione FROM co_rivalse WHERE id=idrivalsainps) AS rivalsainps_desc,

View File

@ -704,9 +704,9 @@ class Fattura extends Document
*/
public function getBanca()
{
$riba = database()->fetchOne('SELECT riba FROM co_pagamenti WHERE id ='.prepare($this->idpagamento));
$pagamento = $this->pagamento;
if ($riba['riba'] == 1) {
if ($pagamento->isRiBa()) {
$banca = Banca::where('id_anagrafica', $this->idanagrafica)
->where('predefined', 1)
->first();

View File

@ -421,6 +421,7 @@ switch (post('op')) {
$intervento->codice_cup = $documento->codice_cup;
$intervento->codice_cig = $documento->codice_cig;
$intervento->num_item = $documento->num_item;
$intervento->idreferente = $documento->idreferente;
$intervento->save();

View File

@ -397,6 +397,7 @@ switch (post('op')) {
$ordine->codice_cup = $documento->codice_cup;
$ordine->codice_cig = $documento->codice_cig;
$ordine->num_item = $documento->num_item;
$ordine->idreferente = $documento->idreferente;
$ordine->save();

View File

@ -48,7 +48,6 @@ switch (filter('op')) {
'giorno' => $giorno,
'prc' => post('percentuale')[$key],
'descrizione' => $descrizione,
'riba' => post('riba'),
'idconto_vendite' => post('idconto_vendite'),
'idconto_acquisti' => post('idconto_acquisti'),
'codice_modalita_pagamento_fe' => post('codice_modalita_pagamento_fe'),

View File

@ -31,16 +31,12 @@ include_once __DIR__.'/../../core.php';
<div class="panel-body">
<div class="row">
<div class="col-md-6">
<div class="col-md-8">
{[ "type": "text", "label": "<?php echo tr('Descrizione'); ?>", "name": "descrizione", "value": "$descrizione$", "required": 1 ]}
</div>
<div class="col-md-4">
{[ "type": "select", "label": "<?php echo tr('Codice Modalità (Fatturazione Elettronica)'); ?>", "name": "codice_modalita_pagamento_fe", "value": "$codice_modalita_pagamento_fe$", "values": "query=SELECT codice as id, CONCAT(codice, ' - ', descrizione) AS descrizione FROM fe_modalita_pagamento", "required": 1 ]}
</div>
<div class="col-md-2">
{[ "type": "checkbox", "label": "<?php echo tr('Pagamento di tipo Ri.Ba.'); ?>", "name": "riba", "value": "$riba$", "help": "<?php echo tr('Abilitando questa impostazione, nelle fatture verrà visualizzata la banca della controparte'); ?>" ]}
{[ "type": "select", "label": "<?php echo tr('Codice Modalità (Fatturazione Elettronica)'); ?>", "name": "codice_modalita_pagamento_fe", "value": "$codice_modalita_pagamento_fe$", "values": "query=SELECT codice as id, CONCAT(codice, ' - ', descrizione) AS descrizione FROM fe_modalita_pagamento", "required": 1, "help": "<?php echo tr('Impostando il codice MP12 il pagamento viene considerato di tipo Ri.Ba.: nelle fatture verrà visualizzata la banca della controparte'); ?>" ]}
</div>
</div>

View File

@ -111,4 +111,12 @@ class Pagamento extends Model
return $results;
}
/**
* @return bool
*/
public function isRiBa()
{
return $this->codice_modalita_pagamento_fe == 'MP12';
}
}

View File

@ -333,7 +333,7 @@ $(document).ready(function() {
dropOnEmpty: true,
scroll: true,
update: function(event, ui) {
let order = $(".table tr[data-id]").toArray().map(a => $(a).data("id"))
let order = $(".table .sortable tr[data-id]").toArray().map(a => $(a).data("id"))
$.post(globals.rootdir + "/actions.php", {
id: ui.item.data("id"),

View File

@ -157,4 +157,11 @@ ALTER TABLE `co_righe_documenti` ADD INDEX(`idpreventivo`);
INSERT INTO `zz_prints` (`id_module`, `is_record`, `name`, `title`, `filename`, `directory`, `previous`, `options`, `icon`, `version`, `compatibility`, `order`, `predefined`, `default`, `enabled`) VALUES ((SELECT `zz_modules`.`id` FROM `zz_modules` WHERE `zz_modules`.`name`='Anagrafiche'), '1', 'Dettaglio anagrafica', 'Dettaglio anagrafica', 'Anagrafica {codice} - {ragione_sociale}', 'anagrafiche', 'idanagrafica', '', 'fa fa-print', '', '', '0', '1', '1', '1');
-- Aggiunta stampa dati aziendali
INSERT INTO `zz_prints` (`id_module`, `is_record`, `name`, `title`, `filename`, `directory`, `previous`, `options`, `icon`, `version`, `compatibility`, `order`, `predefined`, `default`, `enabled`) VALUES ((SELECT `zz_modules`.`id` FROM `zz_modules` WHERE `zz_modules`.`name`='Anagrafiche'), '1', 'Dati aziendali', 'Dati aziendali', 'Dati aziendali {ragione_sociale}', 'azienda', 'idanagrafica', '', 'fa fa-print', '', '', '0', '0', '0', '1');
INSERT INTO `zz_prints` (`id_module`, `is_record`, `name`, `title`, `filename`, `directory`, `previous`, `options`, `icon`, `version`, `compatibility`, `order`, `predefined`, `default`, `enabled`) VALUES ((SELECT `zz_modules`.`id` FROM `zz_modules` WHERE `zz_modules`.`name`='Anagrafiche'), '1', 'Dati aziendali', 'Dati aziendali', 'Dati aziendali {ragione_sociale}', 'azienda', 'idanagrafica', '', 'fa fa-print', '', '', '0', '0', '0', '1');
-- Correzione per segmenti con pagamenti RiBa per Scadenzario
UPDATE `zz_segments` SET `clause` = REPLACE(`clause`, 'co_pagamenti.riba=1', 'co_pagamenti.codice_modalita_pagamento_fe= ''MP12''');
ALTER TABLE `co_pagamenti` DROP `riba`;
-- Aggiunto filtro in contratti per i clienti
INSERT INTO `zz_group_module` (`idgruppo`, `idmodule`, `name`, `clause`, `position`, `enabled`, `default`) VALUES(4, 31, 'Mostra i contratti ai clienti coivolti', 'co_contratti.idanagrafica=|id_anagrafica|', 'WHR', 1, 1);