Documentation technique des règles de validation, de contrôle et de mise à jour implémentées dans la fenêtre de maintenance des domiciles du logiciel ULIS CS (PowerBuilder 9). Source : w_m_dom.txt — Université de Liège (ULiège).
La fenêtre w_m_dom est le composant central de gestion des domiciles dans ULIS CS.
Elle implémente 9 règles métier distinctes, couvrant la validation de saisie,
les contrôles d'intégrité référentielle, les alertes légales et la gestion concurrentielle.
Interdit le caractère ; dans les champs d'adresse (domlib, domrue, domnuo, domboi, domloc) pour éviter la corruption des exports CSV/DMFA.
Résolution automatique de la localité (domloc) à partir du code postal belge via le dictionnaire CPOS. Initialise aussi le pays par défaut (DEF_DOMPAY).
Affiche une information légale non bloquante (message 10526) lorsque le pays du domicile diffère de BEL. Parse la localité étrangère pour extraire le code postal et la commune.
Détecte si un agent du foyer possède un dossier de contrôle médical actif (PHMSER) lors du changement de code postal. Émet des avertissements cumulés via guo_msg.
Impose la continuité absolue des périodes d'adresse (sans trous ni chevauchements). Scinde automatiquement la période précédente à DateDebutNouvelle - 1 jour.
Rend le code postal obligatoire pour tout domicile belge si le paramètre $FORCECPOS$ est actif. Bloque la sauvegarde et force le focus sur le champ manquant.
Pose un verrou exclusif (guo_lock.uf_lockdom) sur tous les cohabitants du foyer dès le chargement. Supporte le paramètre $NOLOCK= pour les traitements automatisés.
Lors d'un changement de pays ou de cohabitants, invalide les carrières concernées pour recalcul REGEN différé. Met à jour le code postal des ménages CSAN en cascade.
Protège les données centrales en architecture distribuée. Bloque toute modification locale d'un domicile ou matricule importé d'ULIS Central (ID < 500 000).
Fichier source : w_m_dom.txt · Fonction : dw_dom::itemchanged · Lignes : 1250–1262
Cette règle interdit l'utilisation du caractère point-virgule (;) dans les champs
de texte décrivant l'adresse.
Pas de référence dans le Guide ULIS CS v11.
« La plupart du temps, il faut vérifier qu'il n'y ait pas de "point-virgule" ou ";" dans une des données reprises ici : domlib, domrue, domnuo, domboi et domloc. S'il y a un ";" dans une de ces données, le message d'avertissement est activé et visible, et l'on ne peut pas passer à une autre zone. »
ULIS CS exporte des fichiers d'échanges ou des flux textuels formatés (CSV ou formats plats délimités par des points-virgules) vers les institutions nationales (Banques/SEPA, DmfA, Medex). La présence d'un point-virgule dans l'adresse corromprait la structure du fichier d'export.
Lors de la modification de l'un des champs de l'adresse (domlib, domrue, domnuo, domboi, domloc) :
;.guo_msg.uf_msg
(message 12236, libellé 12234 : "L'adresse ne peut pas comporter de « ; ». Veuillez corriger.").1 (return 1), ce qui rejette le changement et conserve le focus sur le champ.// IA : Vérification sur les champs textuels de l'adresse pour interdire l'utilisation du point-virgule (";").
if pos("domlib domrue domnuo domboi domloc", lower(dwo.name)) > 0 then
lb_fip = uf_getfilterinprogress()
uf_setfilterinprogress (True)
// IA : Si un point-virgule est détecté dans la valeur saisie (data), un message d'avertissement est affiché et la saisie est rejetée.
if pos(data, ";") > 0 then
// 12236 "Le libellé est invalide" 12234 "L'adresse ne peut pas comporter de « ; ». Veuillez corriger."
guo_msg.uf_msg(uf_getwindowparent(), 12236, guo_dict.uf_olex(12234), 'warning')
uf_setfilterinprogress(lb_fip)
// IA : Retourne 1 pour bloquer l'acceptation de la saisie et conserver le focus sur le champ actuel.
return 1 // no accept, no focus change
end if
uf_setfilterinprogress(lb_fip)
end ifFichier source : w_m_dom.txt · Fonction : dw_dom::itemchanged · Lignes : 1266–1289
Cette règle automatise la saisie de la commune en fonction du code postal encodé.
« La zone « Localité » est automatiquement complétée par ULIS CS dès que vous acceptez le code postal. Le ' ?' initial signifie 'Inconnu'. »
« Le code postal belge est basé sur le dictionnaire OLDICT='CPOS', qui permet d'ailleurs de trouver, du coup, la localité belge concernée. »
« de plus, si le code postal belge existe, la localité existe aussi et le code postal permet d'encoder directement la localité (même si l'agent responsable peut la modifier par la suite). »
Pour éviter les erreurs de saisie et garantir l'homogénéité des données d'adressage
vers les organismes officiels belges, le système s'appuie sur le dictionnaire CPOS.
À la saisie ou modification du code postal (domcpo) :
CPOS via guo_dict.uf_gettextwithdate.domloc est automatiquement mis à jour.? ou est vide), le pays est initialisé
à la valeur par défaut DEF_DOMPAY (généralement BEL).case 'domcpo'
// IA : Recherche de la localité associée au code postal saisi (data) dans le dictionnaire officiel 'CPOS' à la date du jour.
ls = guo_dict.uf_gettextwithdate ('CPOS', data, today ())
if ls <> '' then
// IA : Sauvegarde de l'état du filtre en cours pour éviter les boucles d'événements.
lb_fip = uf_getfilterinprogress ()
uf_setfilterinprogress (True)
// Sets name of city
// IA : Remplacement automatique de la localité (domloc) par celle retournée par le dictionnaire.
setitem (row, 'domloc', ls)
// Sets default name of country if none
// IA : Vérification si le pays est défini. Si vide, nul ou '?', il est automatiquement complété avec le pays par défaut.
ls_pays = getitemstring (row, 'dompay')
lb_setdefpays = isnull (ls_pays)
if not lb_setdefpays then lb_setdefpays = (trim (ls_pays) = '?' or trim (ls_pays) = '')
if lb_setdefpays then
// IA : Récupération du pays par défaut dans le dictionnaire SYST (DEF_DOMPAY).
ls_pays = guo_dict.uf_gettext ('SYST', 'DEF_DOMPAY')
if ls_pays = '' then
guo_msg.uf_msgw (00002, '@00009 : SYST ("DEF_DOMPAY" ?)')
ls_pays = '?'
end if
setitem (row, 'dompay', ls_pays)
end if
uf_setfilterinprogress (lb_fip)
end ifFichier source : w_m_dom.txt · Fonctions : dw_dom::itemchanged, wf_informationbox_if_agent_lives_abroad · Lignes : 1321–1332, 679–704
Cette règle affiche une alerte légale informative lorsque le pays du domicile est défini en dehors de la Belgique.
« Et si vous ne connaissez pas le nouveau domicile de la personne qui déménage ? Ajoutez-lui tout de même un nouveau domicile en laissant vides les zones facultatives (Libellé, Rue, Numéro, Boîte et Code Postal) et en remplaçant les informations obligatoires (Localité et pays) par des « ? ». »
« si la personne physique habite à l'étranger (donc pas en Belgique), alors on active un message donnant le code postal et la localité de l'adresse à l'étranger. Ce message n'est pas bloquant mais si la personne physique n'a pas de code postal ou de localité, alors ce sera aux risques et périls de l'agent chargé d'encoder la nouvelle adresse de cette personne. C'est effectué à partir de : wf_informationbox_if_agent_lives_abroad(dompay, domloc) »
Les agents résidant à l'étranger sont assujettis à des règles fiscales et sociales spécifiques (calcul de la DmfA / NISS, exclusion éventuelle de certaines obligations territoriales belges).
Lors du changement du pays (dompay) ou de la localité (domloc) dans dw_dom :
BEL), le système appelle wf_informationbox_if_agent_lives_abroad.10526
et les libellés 10364 (code postal) et 10365 (localité).// ==================== dw_dom::itemchanged ====================
case 'dompay'
// IA : Si le pays du domicile est modifié, on compare avec le pays par défaut de l'institution.
ls_pays = guo_dict.uf_gettext ('SYST', 'DEF_DOMPAY')
if ls_pays = '' then
guo_msg.uf_msgw (00002, '@00009 : SYST ("DEF_DOMPAY" ?)')
ls_pays = '?'
elseif upper(data) <> ls_pays then
// setitem(row,'domcpo',ls_null)
end if
// IA : Si le pays devient étranger, on déclenche l'affichage d'une alerte d'expatriation.
wf_informationbox_if_agent_lives_abroad(data,getItemString(row, 'domloc'))// PO 04/09/03
// IA : Repositionnement ou effacement des colonnes CP/localité selon le pays (Belgique ou étranger).
FUNCTION POST wf_set_cpos()//PG 18/06/00
case 'domloc'
// IA : Si la localité change, on déclenche également l'affichage d'une alerte d'expatriation si le pays est étranger.
wf_informationbox_if_agent_lives_abroad(getItemString(row,'dompay'),data)// PO 04/09/03
// ==================== wf_informationbox_if_agent_lives_abroad ====================
// IA : Affiche une boîte d'information légale si l'agent réside à l'étranger (nécessaire pour la conformité des déclarations sociales DMFA / ONSS).
protected function boolean wf_informationbox_if_agent_lives_abroad (string as_pays, string as_domloc);// PO 04/09/03
// Display an information (cfr WAUTOT_0470_DMFA-NISS absent.doc) if agent lives out of belgium
String ls_code_post, ls_loca
Long ll
// IA : Si le pays est la Belgique (BEL), aucune alerte d'expatriation n'est requise.
If upper(as_pays) = 'BEL' then return true
IF ISNULL(as_domloc) OR ISNULL(as_pays) THEN return true
IF trim(as_domloc) = '' OR trim(as_pays) = '' THEN return true
// IA : Découpage de la localité pour extraire séparément le code postal étranger et le nom de la localité.
ll = pos(as_domloc,' ')
IF ll = 0 THEN
ls_code_post = as_domloc
ELSE
ls_code_post = left(as_domloc, ll - 1)
if ll < len(as_domloc) then
ll = len(as_domloc) - ll
ls_loca = right(as_domloc, ll)
end if
END IF
// IA : Affichage de l'information via la boîte de dialogue système (message 10526).
guo_msg.uf_msgi(10526, guo_dict.uf_olex(10364)+" = ~'"+ ls_code_post+"~', "+guo_dict.uf_olex(10365)+" = ~'" + ls_loca + "~'")
return true
end functionFichier source : w_m_dom.txt · Fonctions : dw_dom::itemchanged, wf_get_medex · Lignes : 1290–1320, 604–663
Cette règle alerte le gestionnaire RH d'une anomalie potentielle de localisation si un agent cohabitant a un dossier médical actif.
Pas de référence dans le Guide ULIS CS v11.
« De plus, si l'on gère le "service traitant du SPMT" (PHMSER = "SPMT : Serv. traitant"), alors on ajoute un message relatif à toutes les personnes physiques du "nouveau" domicile et aux éventuelles personnes morales associées en indiquant que, si la personne physique change de province et fait partie de "MEDEX", il faudra aussi adapter le "MEDEX" associé. »
En Belgique, le service Medex gère le contrôle médical des agents du secteur public en cas d'absence.
Si un agent est sous contrôle médical et que son adresse est modifiée, le médecin contrôleur risque
de se rendre à une mauvaise adresse. Le système interroge immédiatement la table ULIS.U2LIP
pour détecter tout dossier de contrôle médical en cours.
Lors du changement de code postal (domcpo) :
ib_checkmedex est actif, la fonction wf_get_medex interroge ULIS.U2LIP
avec le type de relation PHMSER pour les agents du domicile à la date du jour.00142, libellés 11899 et 11900) listant les agents concernés.guo_msg.uf_show sans bloquer la sauvegarde.// ==================== dw_dom::itemchanged ====================
// VK 16/10/06
// IA : Si le contrôle médical Medex est activé (ib_checkmedex), on vérifie les dossiers médicaux en cours pour les agents domiciliés à cette adresse.
IF ib_checkmedex THEN
ll_count = wf_get_medex(ll_permats[], ll_medexs[])
// 00142 11899 11900
// IA : Insertion de messages d'avertissement dans le gestionnaire de messages guo_msg pour notifier le gestionnaire d'un possible conflit de localisation Medex.
guo_msg.uf_insert(parent, 00142, guo_dict.uf_olex(11899), 'warning')
guo_msg.uf_insert(parent, 00142, guo_dict.uf_olex(11900), 'warning')
guo_msg.uf_insert(parent, 00142, '', 'warning')
IF ll_count > 0 THEN
CHOOSE CASE gs_language
CASE '1'
guo_msg.uf_insert(parent, 00142, 'Actuellement: ', 'warning')
CASE '2'
guo_msg.uf_insert(parent, 00142, 'Nu:', 'warning')
CASE ELSE
guo_msg.uf_insert(parent, 00142, '', 'warning')
END CHOOSE
FOR ll = 1 TO ll_count STEP +1
// IA : Itère sur chaque cohabitant impacté pour lister les dossiers de contrôle médical (PMOS) actifs.
IF ll_medexs[ll] = 0 THEN
guo_msg.uf_insert(parent, 00142, guo_dict.uf_gettext('PPHS', String(ll_permats[ll], '000000'), '1') + &
' => ?', &
'warning')
ELSE
guo_msg.uf_insert(parent, 00142, guo_dict.uf_gettext('PPHS', String(ll_permats[ll], '000000'), '1') + &
' => ' + &
guo_dict.uf_gettext('PMOS', String(ll_medexs[ll], '000000'), '1'), &
'warning')
END IF
NEXT
END IF
guo_msg.uf_show(parent, 00142, luo_null)
END IF
// ==================== wf_get_medex ====================
// IA : Recherche s'il existe des dossiers médicaux (service de contrôle médical) actifs à ce jour pour les agents habitant le domicile.
private function long wf_get_medex (ref long al_permats[], ref long al_medexs[]);// VK 16/10/06
Datetime ldt_now
String ls_msg, ls_pphinfo
Long ll_permats[]
Long ll_medexs[]
Long ll_row, ll_permat, ll_medex, ll_1, ll_2
ldt_now = Datetime(Today(), Now())
// IA : Parcours de tous les cohabitants (dw_lidcoh) pour trouver les matricules d'agents.
FOR ll_Row = dw_lidcoh.RowCount() TO 1 STEP -1
IF dw_lidcoh.getItemString(ll_row, 'lidnat') = 'PERMAT' THEN
ll_permat = dw_lidcoh.getItemNumber(ll_row, 'lidvan')
// IA : Analyse de l'information signalétique pour s'assurer que la personne physique possède un numéro administratif (agent actif).
ls_pphinfo = guo_dict.uf_gettext('PPH1', string (ll_permat, '0000000000'), '1')
ll_1 = 0 ; ll_2 = 0
ll_1 = Pos(ls_pphinfo, '²')
IF ll_1 > 0 THEN
ll_2 = Pos(ls_pphinfo, '²', ll_1 + 1)
IF ll_2 < 1 THEN ll_2 = Len(ls_pphinfo) + 1
END IF
IF (ll_1 = 0) OR (ll_2 = 0) OR (ll_2 = ll_1 + 1) THEN
CONTINUE // No numadm => not an agent => skip permat
END IF
// IA : Requête SQL pour vérifier si un dossier médical (PHMSER) est actif à la date/heure actuelle.
SELECT "ULIS"."U2LIP"."LIDVAN"
INTO :ll_medex
FROM "ULIS"."U2LIP"
WHERE ( "ULIS"."U2LIP"."LIDNAT" = 'PHMSER' ) AND
( "ULIS"."U2LIP"."LIDEXT" = :ll_permat ) AND
( "ULIS"."U2LIP"."LIDEXN" = 'PH' ) AND
(:ldt_now between "ULIS"."U2LIP"."LIDDEB" and "ULIS"."U2LIP"."LIDFIN") USING sqlca1 ;
// IA : Gestion du code retour SQL (SQLCode) et validation de la transaction ou rollback en cas d'erreur.
IF sqlca1.SQLCode < 0 THEN
ls_msg = sqlca1.uf_getMsg()
sqlca1.uf_rollBack()
guo_msg.uf_msge(00002, ls_msg)
RETURN 0
ELSEIF sqlca1.SQLCode > 0 THEN // NOT found
sqlca1.uf_commitI()
ll_permats[UpperBound(ll_permats[]) + 1] = ll_permat
ll_medexs[UpperBound(ll_medexs[]) + 1] = 0
CONTINUE
ELSE
sqlca1.uf_commitI()
ll_permats[UpperBound(ll_permats[]) + 1] = ll_permat
ll_medexs[UpperBound(ll_medexs[]) + 1] = ll_medex
END IF
END IF
NEXT
al_permats[] = ll_permats[]
al_medexs[] = ll_medexs[]
RETURN UpperBound(al_permats[])
end functionFichier source : w_m_dom.txt · Fonctions : dw_dom::ue_insertrow, dw_lidcoh::ue_deleterow · Lignes : 1183–1191, 1630–1635
Cette règle impose la continuité absolue des adresses au cours de la vie de l'agent et contrôle la scission des périodes.
« Vous devez être attentif au fait que toute personne physique ne peut avoir qu'un et un seul domicile pendant une même période, mais DOIT en avoir un, et ce depuis sa date de naissance. Au niveau du domicile, la continuité des périodes est obligatoire. »
« En outre, vous devez être attentif au fait que vous ne pouvez jamais modifier les dates de validité d'un domicile. La seule chose que vous puissiez faire, c'est ajouter un domicile avec une nouvelle date de début de validité. »
« Une personne physique aura toujours une adresse au départ, quitte à ce que celle-ci reste à "?" dans certains cas spécifiques. A un moment donné, une personne peut changer d'adresse. Dans ce cas, l'encodage de l'ancienne adresse se termine à la date de fin donnée et celui de la nouvelle adresse débute à la date de début de cette nouvelle adresse, le lendemain de la date de fin de l'ancienne adresse. »
« Si c'est bon, l'ancien domicile de cette personne se termine à la veille du début du domicile concerné. Le reste est classique, avec l'ajout du matricule au niveau du nouveau domicile, la fin de ce même matricule à la veille pour l'ancien domicile... »
« A la suppression d'un matricule... 2. Vérifications de la dernière date de ce matricule juste avant celle du domicile et remise à jour de ce matricule à "+ l'infini" pour ce "domicile précédent qui redevient l'actuel". »
Les tables d'adressage BDA et BVA gèrent les adresses par périodes historiques successives. La continuité temporelle (sans trous ni chevauchements) est indispensable pour les déclarations fiscales et sociales rétroactives.
À l'insertion d'une nouvelle période :
guo_dateddw.uf_insert insère la ligne et ajuste automatiquement
la date de fin de la période précédente à DateEffet - 1 jour.À la suppression :
gd_deb à gd_fin), à moins d'une confirmation explicite (dialogue 11046).// IA : Règle de continuité et d'unicité temporelle. Insertion d'une nouvelle période d'adresse pour dw_dom.
// IA : L'appel à guo_dateddw.uf_insert gère la scission automatique de la période en cours et assure la continuité.
if not guo_entry.uf_datesentry(ld_deb,ld_null,gd_deb,gd_fin,'') then return
if isnull(ld_deb) then return
if ib_new_dom_the_first_of_the_month then ld_deb = Date(Year(ld_deb),Month(ld_deb),1)
if not guo_dateddw.uf_insert(this,'1=1',gd_deb,gd_fin) then return
ll=ilog.istr_date.tl_key;setnull(ilog.istr_date.tl_key)//force key change for scrolltokey
uf_scrolltokey(ll)
// IA : Règle d'unicité et de maintien d'une période par personne physique.
// IA : Si l'utilisateur tente de supprimer la dernière période de cohabitation (couvrant gd_deb à gd_fin), une confirmation est requise.
if date(getitemdatetime(ll,2))=gd_deb and date(getitemdatetime(ll,3))=gd_fin then //last row delete for this permat !
if guo_msg.uf_msg(parent,11046,'','confirm')='KO' then return
deleterow(ll)
wf_scroll(uf_getdatevisu(),ll_1)
return
end ifFichier source : w_m_dom.txt · Fonctions : wf_check_if_cpos_encoded, wf_window, dw_dom::ue_insertrow, dw_lidcoh::ue_hist · Lignes : 1012–1041, 498–505, 1164–1170, 1538–1544
Cette règle impose la saisie obligatoire d'un code postal pour tout domicile situé en Belgique.
« Lorsque vous encodez que l'agent est domicilié en Belgique, ULIS CS va ajouter une zone « Code Postal », destinée à recevoir le code postal, au besoin via l'option « Dictionnaire » du menu contextuel. »
« Si le domicile est hors Belgique, il n'y a qu'une zone localité dans laquelle il faut encoder le code postal et la localité. »
« Si le pays est "Belgique", alors le code postal est très utile voire, dans certains cas, indispensable (par ex. pour les déclarations fiscales annuelles, DIMONA, DMFA, etc.). »
« 1. On commence par vérifier le code postal si nécessaire (si pas bon => retour sans sauver) ; »
L'adresse de résidence conditionne le calcul de la fiscalité locale (taxes communales et régionales)
dans les déclarations DmfA et précompte professionnel. L'absence de code postal invalide
la déclaration de paie. Si le pays correspond à DEF_DOMPAY (configuré à BEL par défaut),
le code postal est strictement obligatoire pour sauvegarder.
Si le paramètre $FORCECPOS$ est actif et que l'utilisateur valide un domicile belge sans code postal :
domcpo de la DataWindow dw_dom.00003) est affiché.// IA : Cette fonction valide que le code postal (domcpo) est renseigné si le pays est la Belgique (défini par DEF_DOMPAY dans le dictionnaire SYST).
private function boolean wf_check_if_cpos_encoded ();// VK 01/12/14
String ls_cpos
// IA : Si le dictionnaire global n'est pas valide, on court-circuite la validation.
IF NOT Isvalid(guo_dict) THEN RETURN True
// IA : Si le pays du domicile n'est pas le pays par défaut (Belgique), le code postal n'est pas obligatoire.
if dw_dom.getitemstring(1,'dompay') <> guo_dict.uf_gettext ('SYST', 'DEF_DOMPAY') then
RETURN True
END IF
ls_cpos = dw_dom.getitemstring(1,'domcpo')
// IA : Si le code postal n'est pas nul et a une longueur après trim > 0, la validation réussit.
IF NOT isNull(ls_cpos) THEN
IF Len(Trim(ls_cpos)) > 0 THEN
RETURN True
END IF
END IF
// IA : En cas d'échec, on force le focus sur la colonne 'domcpo' de la datawindow des domiciles (dw_dom).
dw_dom.SetColumn('domcpo')
IF isValid(dw_dom) THEN
IF GetFocus() <> dw_dom THEN
dw_dom.setFocus()
END IF
END IF
// IA : On affiche un message d'aide (numéro 00003) pour avertir l'utilisateur.
guo_msg.uf_mhelpw( 00003, '')
RETURN FAlse
end functionFichier source : w_m_dom.txt · Fonctions : dw_lid::retrieveend, wf_lockper · Lignes : 1428–1439, 822–842
Cette règle protège les dossiers des agents contre les modifications simultanées en posant un verrou sur tous les domiciliés du foyer concerné.
Pas de référence dans le Guide ULIS CS v11.
« l'action initiale "locke" soit une seule donnée... soit toutes les personnes physiques associées à ce domicile à un moment donné... elle ne permet donc pas qu'un autre agent puisse éventuellement modifier des données du même domicile. »
« Rien de spécifique ici si ce n'est le fait, au "retrieveend", de "locker" le domicile, ou plus précisément toutes les personnes associées à ce domicile à un moment donné... »
Un domicile (W_M_DOM) est une entité partagée pouvant relier plusieurs cohabitants (membres d'un ménage).
Si un gestionnaire modifie l'adresse, l'impact se répercute sur tous les agents rattachés.
Pour éviter les conflits d'accès concurrentiels, le système verrouille chacun des cohabitants
identifiés par son matricule (PERMAT).
Au chargement initial des cohabitants dans dw_lid :
guo_lock.uf_lockdom pour poser un verrou exclusif.ue_cancel),
le flag de modification est désactivé et l'accès est bloqué.$NOLOCK= (analysé par wf_lockper) permet d'exclure certains matricules
spécifiques du verrouillage, typiquement pour les traitements en lot ou d'automatisation.// ==================== dw_lid::retrieveend ====================
// IA : Règle de verrouillage concurrentiel. Lors du retrieveend des cohabitants du domicile, le système tente de verrouiller en édition chaque matricule (PERMAT).
// IA : Si le verrouillage échoue (déjà verrouillé par un autre utilisateur), l'édition est désactivée et la modification annulée.
if not ib_visu then
if not guo_lock.uf_lockdom(ll_1,is_locklist) then
dw_dom.istr_base.tb_update=false;dw_lid.istr_base.tb_update=false
dw_lidcoh.istr_base.tb_update=false
// Trigger of ue_cancel in "open" process => GPF !!!
if guo_open.ib_openinprogress then ib_lockedatopen = true &
else parent.postevent('ue_cancel')
// "RETURN" is ABSOLUTELY necessary here, otherwise process goes on, but
// window could still be refered to by this script (or other ones !!!)
RETURN -1
end if
end if
// ==================== wf_lockper ====================
// IA : Fonction d'acquisition du verrou sur un matricule d'agent. Permet d'ignorer le verrouillage si l'agent est explicitement exclu via le paramètre $NOLOCK=.
private function boolean wf_lockper (long al_permat, ref string as_locklist);//GF 01/10/10 Lock permat except if exclusion list $NOLOCK=$
//GF 02/08/12 Add as_lockList, don't use is_lockList
string ls_PermatList, ls_Permat
if Pos(istr_objectparm.ts_viewparm, "$NOLOCK=") > 0 then
ls_Permat = String(al_Permat)
wf_Unstrip(istr_objectparm.ts_viewparm, "$NOLOCK=", ls_PermatList)
if IsNull(ls_PermatList) or ls_PermatList = "" or (Pos(ls_PermatList, ls_Permat) <= 0) then
return guo_lock.uf_lockPer(al_permat, as_locklist)
else
return true // permat is in list so no lock
end if
else
return guo_lock.uf_lockPer(al_permat, as_locklist)
end if
return true
end functionFichier source : w_m_dom.txt · Fonctions : wf_window, wf_updatecsan · Lignes : 562–575, 579–598, 265–305
Cette règle garantit la mise à jour cohérente du statut de cohabitation et le recalcul des carrières lors du changement de domicile.
Pas de référence dans le Guide ULIS CS v11.
« Ensuite, si l'on gère le "centre de santé" (ib_phcsan) a changé, il faut confirmer l'éventuel changement... »
« 2. Ensuite, on vérifie si les carrières (dossiers administratifs, pécuniaires, etc.) doivent être modifiées (le pays du domicile et/ou les cohabitants peuvent avoir changé), d'où il faut, si nécessaire, invalider le ou les dossiers concernés ; »
« 3. Enfin, on vérifie aussi, si nécessaire, si le centre de santé est correct (sinon, on retourne avec un avertissement, sans sauver et sans sortir de la fenêtre). »
« Cette fonction [wf_super_window] inspecte, si nécessaire, les modifications qui ont été introduites dans les trois datawindows dw_dom, dw_lid et dw_lidcoh, et sur base de celles-ci, retourne la liste des matricules dont l'historique des domiciliations serait modifié si la sauvegarde était effectuée maintenant. »
Un changement d'adresse peut modifier le statut de cohabitation fiscale ou sociale (CSAN).
Tout changement doit être propagé aux cohabitants déclarés et forcer le recalcul du moteur
de paie/statut (processus REGEN différé).
Lors de la sauvegarde globale (wf_window) avec l'option UPDATE :
REGEN) sont remplies (changement de pays DOMPAY ou
modification des cohabitants dw_lidcoh), le système parcourt chaque membre du ménage.guo_lock.uf_lockdosshared) et invalide
formellement sa carrière (guo_mgr.uf_invalidate_permat), déclenchant son recalcul au prochain batch REGEN.ib_phcsan), wf_updatecsan met à jour en cascade le code postal
des ménages concernés via u_nv_updatecsan. Si la mise à jour échoue, un rollback SQL est opéré.// ==================== wf_window ====================
// Invalidation of all (co)resident careers
// IA : Si un élément déclencheur de recalcul est modifié (ex: pays ou cohabitants), invalider les carrières associées pour planification d'un REGEN différé.
if lb_regen then
for ll = dw_lidcoh.RowCount() to 1 step -1
ll_permat = dw_lidcoh.GetItemNumber(ll, 'lidvan')
if ll_permat > 0 then
// IA : Verrouillage partagé du dossier de l'agent pour modification sécurisée.
if not guo_lock.uf_lockdosshared(ll_permat , is_locklist) then
guo_msg.uf_msgw(11028, guo_dict.uf_olex(00007))
return false
end if
if not ib_uliscmed then //LS 22/03/05 : malvoz
// IA : Invalidation formelle de la carrière de l'agent dans guo_mgr.
if not guo_mgr.uf_invalidate_permat(ll_permat, false) then return false
end if
end if
next
end if
end if
//RO 30/07/09
// IA : Si l'option d'intégrité CSAN est active (ib_phcsan), mettre à jour en cascade les dossiers cohabitants lors d'un UPDATE.
if upper(as_options) = 'UPDATE' and ib_phcsan then
if dw_dom.rowCount() > 0 then
String ls_domcpo
ls_domcpo = dw_dom.getItemString(1, 'domcpo')
// IA : Propagation du code postal (ls_domcpo) à l'ensemble du ménage / cohabitants via la fonction wf_updatecsan.
if not wf_updatecsan(ls_domcpo) then
dw_dom.itr.uf_rollback()
return false
end if
else
return wf_super_window(as_options)
end if
// IA : Commit ou rollback de la transaction SQL en fonction du résultat de la sauvegarde globale (wf_super_window).
if wf_super_window(as_options) then
dw_dom.itr.uf_commiti()
return true
else
dw_dom.itr.uf_rollback()
return false
end if
end if
// ==================== wf_updatecsan ====================
// IA : Met à jour la table des cohabitants (PHCSAN) avec le code postal as_cpo pour l'ensemble des habitants identifiés par PERMAT.
protected function boolean wf_updatecsan (string as_cpo);//RO 30/07/09 21/08/09
//GF 26/02/10
//GF 01/10/10 call wf_LockPer
//GF 02/08/12 Use ls_lockList not is_lockList
//RO 27/09/13 Refactoring
//GF 26/07/24 Vérifie as_cpo (SVICOMF-2336)
//Updates the PHCSAN given the post code as_cpo for all the inhabitant if necessary. Commit have to be done by calling function !
//Returns true if succeeds, false otherwise.
long ll_permat, ll_count, ll_i, ll_isAgent, ll_return, ll_umax, ll_phcsan_new
datetime ldt_new, ldt_newm1, ldt_fin
string ls_msg, ls
string ls_lockList
u_nv_updatecsan luo_csan
// IA : Instanciation de l'objet de gestion de mise à jour CSAN (u_nv_updatecsan).
luo_csan = create u_nv_updatecsan
luo_csan.uf_constructor(dw_dom.itr,istr_objectparm.ts_viewparm,f_map())
ll_count = dw_lidcoh.rowCount()
// IA : Itération sur tous les cohabitants enregistrés dans la datawindow (dw_lidcoh).
for ll_i = 1 to ll_count
// IA : Seuls les matricules physiques d'agents (PERMAT) sont concernés.
if dw_lidcoh.getItemString(ll_i, 'lidnat') <> 'PERMAT' then continue
ll_permat = dw_lidcoh.getItemNumber(ll_i,'lidvan')
ldt_new = dw_lidcoh.getItemDatetime(ll_i,'liddeb')
ldt_fin = dw_lidcoh.getItemDatetime(ll_i,'lidfin')
//RO 27/09/13 Centralize the business logic because we need to call it in w_m_dosu2
// GF 26/07/24
// IA : Si le code postal est nul, mise à jour simple sans code postal. Sinon, mise à jour ciblée avec le code postal.
if isNull(as_cpo) then
// J'ai l'impression que cela ne sert a rien si on ne donne pas un code postal
if not luo_csan.uf_update(ll_permat, ldt_new, ldt_fin) then return false
else
if not luo_csan.uf_update(ll_permat,as_cpo,ldt_new,ldt_fin) then return false
end if
next
if isValid(luo_csan) then destroy luo_csan
return true
end functionFichier source : w_m_dom.txt · Fonctions : dw_lidcoh::ue_deleterow, dw_lidcoh::ue_insertrow, wf_open2 · Lignes : 1609–1627, 1666–1672, 1688–1699, 752–763
Contexte de migration : Bien que cette règle soit documentée par Vincent Kieffer comme obsolète pour la future cible de production (les serveurs satellites distribués n'étant plus d'actualité), elle reste pleinement active dans le code source PowerBuilder 9 analysé. Elle doit donc être prise en compte dans l'analyse de l'existant.
Cette règle protège l'intégrité des données centrales d'adressage dans un déploiement décentralisé satellite µULIS.
Pas de référence dans le Guide ULIS CS v11.
« La partie MicroUlis (ou µULIS) n'est plus d'application, nous ne parlerons donc pas du reste, spécifique à cette partie µULIS. »
« Encore une fois, nous ne parlerons pas de µULIS pour le reste, qui n'a en effet plus lieu d'être. »
Dans l'architecture distribuée d'Ulis CS, certaines entités décentralisées (serveurs satellites
d'hôpitaux ou de facultés) utilisent une base locale appelée µulisserver. Pour éviter des
désynchronisations avec la base centrale d'ULIS (alimentée par le Registre National),
les agents centraux (ID de personne physique ou domicile < 500000) ne doivent pas être modifiés localement.
Si l'environnement est détecté comme µulisserver :
wf_open2) : si le matricule est < 500000, la DataWindow dw_dom est verrouillée en lecture seule (protected).ue_insertrow) ou suppression (ue_deleterow) d'un cohabitant dans dw_lidcoh :
si l'ID du domicile (il_objectid) ou le matricule (lidvan) est < 500000, l'opération est bloquée.11030).// ==================== dw_lidcoh::ue_deleterow ====================
// IA : Dans un environnement satellite (µulisserver), les modifications sur les domiciles ou matricules importés du serveur central (identifiés par un ID < 500000) sont formellement bloquées.
if not ib_visu and f_getservertype () = 'µulisserver' then
// IA : Bloque si le domicile (il_objectid) provient d'ULIS central.
if il_objectid < 500000 then
// Not allowed to modify a dom coming from ULIS (french msg because µULIS only) !!!
guo_msg.uf_msg (parent, 11030, "Domicile provenant d'ULIS !", 'warning')
RETURN
end if
end if
ll=getrow()
if ll=0 then return
ll_1=getitemnumber(ll,'lidvan') // YQ 31/07/00 : Gets agent's matricule
// IA : Bloque si le matricule de l'agent cohabitant (ll_1) provient d'ULIS central.
if not ib_visu and f_getservertype () = 'µulisserver' then
if ll_1 < 500000 then
// Not allowed to modify a dom for a PPH coming from ULIS (french msg because µULIS only) !!!
guo_msg.uf_msg (parent, 11030, "Matricule provenant d'ULIS !", 'warning')
RETURN
end if
end if
// ==================== dw_lidcoh::ue_insertrow ====================
// IA : Dans un environnement satellite (µulisserver), bloquer l'insertion d'un nouveau cohabitant si le domicile courant provient de l'ULIS central.
if not ib_visu and f_getservertype () = 'µulisserver' then
if il_objectid < 500000 then
// Not allowed to modify a dom coming from ULIS (french msg because µULIS only) !!!
guo_msg.uf_msg (parent, 11030, "Domicile provenant d'ULIS !", 'warning')
RETURN
end if
end if
// ... [code d'insertion] ...
// IA : Empêcher l'insertion d'un cohabitant dont le matricule est importé de l'ULIS central (ID < 500000).
if not ib_visu and f_getservertype () = 'µulisserver' then
ll = pos (ls, '$')
if ll > 0 then ls = left (ls, ll - 1)
if len (ls) > 0 then
ll = long (ls)
if ll < 500000 then
// Not allowed to modify a dom for a PPH coming from ULIS (french msg because µULIS only) !!!
guo_msg.uf_msg (parent, 11030, "Matricule provenant d'ULIS !", 'warning')
RETURN
end if
end if
end if
// ==================== wf_open2 ====================
// protect bda if ULIS permat in µULIS (=> local adresses only for local people !)
// IA : En mode µULIS, si l'agent identifié par il_objectid est un agent central (ID < 500000), son domicile est verrouillé en lecture seule.
if not ib_visu and f_getservertype () = 'µulisserver' then
if il_objectid < 500000 then
dw_dom.uf_settsprotect ('a')
dw_dom.uf_dwmodify ('protected')
dw_lidcoh.uf_popsetoptions ('', 'i', '')
else
dw_dom.uf_settsprotect ('')
dw_dom.uf_dwmodify ('restore')
dw_lidcoh.uf_popsetoptions ('i', '', '')
end if
end if