fmb_login: 5 programs convert in part
Shortest first. Left, the PL/SQL as the form holds it. Right, the clauses in the vocabulary’s spelling and, under them, each refused statement with the converter’s reason. 3 of them are program units, headed on unit: a unit’s refusals belong to the unit and are finished there once, and a caller that inlined one links to it rather than asking for the same work again.
1. fmb_loginWHEN-BUTTON-PRESSED on LOGIN.FORGOT_YOUR_PASSWORDstudy
What you haveWHEN-BUTTON-PRESSED
go_item('REQ_EMAIL');
Center_Window('WIN_PASS');What you getClause Rule Language
on press of FORGOT_YOUR_PASSWORD: call CENTER_WINDOW('WIN_PASS') # 1 statement did not convert.# line 1 # go_item('REQ_EMAIL'); # reason: no single field of this form answers to REQ_EMAIL, and attributing it to whichever block wins is how a clause names a field the trigger never did
1 clause converted, 1 statement refused
2. fmb_loginon unit FORMAT_WINstudy
What you havePROGRAM-UNIT
PROCEDURE FORMAT_WIN
(Window_Name IN VarChar2,
Window_Title IN VarChar2,
Window_Align IN VarChar2)
IS
v_HeightMDI Number;
v_WidthMDI Number;
v_HeightForm Number;
v_WidthForm Number;
v_X Number;
v_Y Number;
v_Curr_Win VarChar2(40);
Begin
v_Curr_Win := Window_Name;
Set_Window_Property(v_Curr_Win, Title, Window_Title);
If Window_Align = 'C' Then
--Centre Form
v_HeightMDI := Get_Window_Property(FORMS_MDI_WINDOW, Height);
v_WidthMDI := Get_Window_Property(FORMS_MDI_WINDOW, Width);
v_HeightForm := Get_Window_Property(v_Curr_Win, Height);
v_WidthForm := Get_Window_Property(v_Curr_Win, Width);
v_X := (v_WidthMDI-v_WidthForm)/2;
v_Y := (v_HeightMDI-v_HeightForm)/2;
Set_Window_Property(v_Curr_Win, Position, v_X, v_Y);
End If;
End;What you getClause Rule Language
on unit FORMAT_WIN(WINDOW_NAME, WINDOW_TITLE, WINDOW_ALIGN): # 1 statement did not convert.# line 15 # Set_Window_Property(v_Curr_Win, Title, Window_Title); # reason: a screen's title is the document's and the platform draws it, and every corpus site reads this one from a local the trigger does not state, so the window property is refused rather than folded into a verb
0 clauses converted, 1 statement refused
3. fmb_loginWHEN-BUTTON-PRESSED on LOGIN.OKstudy
What you haveWHEN-BUTTON-PRESSED
Declare
V_User_Name Varchar2(40);
V_Status Number;
V_Pass_Dt Date;
V_Currency Varchar2(10);
V_Pass_Days Number(3);
V_Mac_Id Varchar2(20);
V_En_Mac_Auth Char(1);
V_Alert Char(1);
V_Port Number(10);
V_Rep_Server Varchar2(50);
V_Pass_Valid Date;
V_User_Status Varchar2(4);
V_Msg Varchar2(200);
V_Ayr_Status Char(1);
V_Master_Pl Varchar2(10);
V_Ayr_Fm Date;
V_Ayr_To Date;
Begin
If :User Is Not Null Then
V_En_Mac_Auth := Fn_Get_User_Param(:User, 'USR_EN_MAC_AUTH');
If Nvl(V_En_Mac_Auth, 'N') = 'Y' And :Get_Mac Is Null Then
Login_Message('Java Not Configured. Exiting Forms!');
Pause;
Exit_Form;
End If;
:Global.User := Upper(:User);
-- Call the main login procedure
Proc_Login_User(:User, :Pass, :Get_Mac, V_Msg, V_Status, V_User_Status);
If V_Status = 1 Then -- Successful login
Assign_Global;
:Global.Pass := Pkg_Encrypt.Hash(:Pass, :Global.User_Salt);
-- ? Handle both 'F' (expired) and 'T' (temporary password) statuses
If V_User_Status In ('F', 'T') Then
If V_User_Status = 'T' Then
Login_Message('You are using a temporary password. Please change your password to proceed!');
Elsif V_User_Status = 'F' Then
Login_Message('Your password has expired. Please change your password to proceed!');
End If;
Pause;
:Global.Passwd_Changed := 'N';
Call_Form('fmb_passwd');
If :Global.Passwd_Changed <> 'Y' Then
Exit_Form;
End If;
End If;
Set_Window_Property(Forms_Mdi_Window,
Title,
:Global.System_Product || ' User: ' || :Global.User_Name || '@' || :Global.Company_Name);
Call_Form('fmb_esmenu', Hide, No_Replace);
Else
Login_Message(V_Msg);
Pause;
Raise Form_Trigger_Failure;
End If;
Else
Login_Message('Please enter username.');
Pause;
End If;
Exception
When Form_Trigger_Failure Then
Raise;
When Others Then
Login_Message('Login error: ' || Sqlerrm);
Pause;
Raise Form_Trigger_Failure;
End;What you getClause Rule Language
on press of OK: warn "Java Not Configured. Exiting Forms!" when is_filled(USER) and ((FN_GET_USER_PARAM(USER, 'USR_EN_MAC_AUTH') = 'Y') and is_blank(GET_MAC)) close screen when is_filled(USER) and ((FN_GET_USER_PARAM(USER, 'USR_EN_MAC_AUTH') = 'Y') and is_blank(GET_MAC)) set GLOBAL.USER to upper(USER) when is_filled(USER) call PROC_LOGIN_USER(USER, PASS, GET_MAC, null, null, null) when is_filled(USER) call ASSIGN_GLOBAL() when is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1) set GLOBAL.PASS to PKG_ENCRYPT.HASH(PASS, GLOBAL.USER_SALT) when is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1) warn "You are using a temporary password. Please change your password to proceed!" when ((is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1)) and ((OUT.PROC_LOGIN_USER.6 = 'F') or (OUT.PROC_LOGIN_USER.6 = 'T'))) and (OUT.PROC_LOGIN_USER.6 = 'T') warn "Your password has expired. Please change your password to proceed!" when (((is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1)) and ((OUT.PROC_LOGIN_USER.6 = 'F') or (OUT.PROC_LOGIN_USER.6 = 'T'))) and not (OUT.PROC_LOGIN_USER.6 = 'T')) and (OUT.PROC_LOGIN_USER.6 = 'F') set GLOBAL.PASSWD_CHANGED to 'N' when (is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1)) and ((OUT.PROC_LOGIN_USER.6 = 'F') or (OUT.PROC_LOGIN_USER.6 = 'T')) open screen FMB_PASSWD when (is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1)) and ((OUT.PROC_LOGIN_USER.6 = 'F') or (OUT.PROC_LOGIN_USER.6 = 'T')) close screen when ((is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1)) and ((OUT.PROC_LOGIN_USER.6 = 'F') or (OUT.PROC_LOGIN_USER.6 = 'T'))) and (GLOBAL.PASSWD_CHANGED <> 'Y') open screen FMB_ESMENU when is_filled(USER) and (OUT.PROC_LOGIN_USER.5 = 1) deny when is_filled(USER) and not (OUT.PROC_LOGIN_USER.5 = 1) else OUT.PROC_LOGIN_USER.4 warn "Please enter username." when not is_filled(USER) # 1 statement did not convert.# line 72 # Exception # When Form_Trigger_Failure Then # Raise; # When Others Then # Login_Message('Login error: ' || Sqlerrm); # Pause; # Raise Form_Trigger_Failure; # reason: it handles FORM_TRIGGER_FAILURE and OTHERS and re-raises, and CRL has no clause that runs when a statement fails: the error path ends the program either way, so the statements above it convert and the handler does not
14 clauses converted, 1 statement refused
4. fmb_loginon unit ASSIGN_GLOBALstudy
What you havePROGRAM-UNIT
PROCEDURE Assign_Global IS
cur_emp SYS_REFCURSOR;
cur_comp SYS_REFCURSOR;
v_Master_Pl Varchar2(10);
v_Ayr_Fm Varchar2(10);
v_Ayr_To Varchar2(10);
v_Ayr_Status Varchar2(10);
BEGIN
Proc_Get_Emp_Init(Upper(:USER), cur_emp);
:Global.Message_Level := '10';
:Global.User := Upper(:USER);
-- ? Fixed: Use single FETCH instead of LOOP (cursors return one row)
IF cur_emp IS NOT NULL THEN
FETCH cur_emp INTO :Global.Company, :Global.Divn_Code, :Global.User_Name,
:Global.Last_Login, :Global.Impers_User, :Global.Startmenu,
:Global.User_Status, :Global.Sman_Code, :Global.Supervisor,
:Global.Location, :Global.Admin, :Global.Prv_Pass,
:Global.Emp_Code, :Global.User_Salt;
CLOSE cur_emp;
-- ? Check if data was actually fetched
IF :Global.Company IS NULL THEN
MESSAGE('Employee data not found.');
Pause;
RAISE Form_Trigger_Failure;
END IF;
ELSE
MESSAGE('Unable to retrieve employee data.');
Pause;
RAISE Form_Trigger_Failure;
END IF;
-- Get company info
Proc_Get_Comp_Init(:Global.Company, :Global.Divn_Code, cur_comp);
-- ? Fixed: Use single FETCH instead of LOOP
IF cur_comp IS NOT NULL THEN
FETCH cur_comp INTO :Global.Company, :Global.Company_Name, :Global.Divn_Code,
:Global.Divn_Name, :Global.Company_Group,
:Global.Basecurrency, :Global.Ayear, :Global.Nxt_Ayear, :Global.Prv_Ayear,
:Global.Rep_Host_Name, :Global.Rep_Port,
:Global.Rep_Server, :Global.No_Days, :Global.Stk_Chk_Type, :Global.Edt_Doc_Days,
:Global.Datetime, :Global.Dateformat, :Global.Dateyearformat,
:Global.Curr_Decimal, :Global.Curr_Format;
CLOSE cur_comp;
-- ? Check if data was actually fetched
IF :Global.Company_Name IS NULL THEN
MESSAGE('Company data not found.');
Pause;
RAISE Form_Trigger_Failure;
END IF;
ELSE
MESSAGE('Unable to retrieve company data.');
Pause;
RAISE Form_Trigger_Failure;
END IF;
-- Get year details
Proc_Get_Init_Dtl(:Global.Company, :Global.Ayear, v_Master_Pl, v_Ayr_Fm, v_Ayr_To, v_Ayr_Status);
:Global.Ayear_Fm := v_Ayr_Fm;
:Global.Ayear_To := v_Ayr_To;
:Global.Ayear_Status := v_Ayr_Status;
:Global.Masterpl := v_Master_Pl;
:Global.Message_Level := '10';
-- Set window title
Set_Window_Property(Forms_Mdi_Window,
Title,
:Global.System_Product || ' User: ' || :Global.User_Name || '@' || :Global.Company_Name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
MESSAGE('No data found for the given criteria.');
Pause;
RAISE Form_Trigger_Failure;
WHEN OTHERS THEN
MESSAGE('Error in Assign_Global: ' || SQLERRM);
Pause;
-- Clean up cursors
BEGIN
IF cur_emp IS NOT NULL THEN
CLOSE cur_emp;
END IF;
EXCEPTION WHEN OTHERS THEN NULL;
END;
BEGIN
IF cur_comp IS NOT NULL THEN
CLOSE cur_comp;
END IF;
EXCEPTION WHEN OTHERS THEN NULL;
END;
RAISE Form_Trigger_Failure;
END;What you getClause Rule Language
on unit ASSIGN_GLOBAL: call PROC_GET_EMP_INIT(upper(USER), null) set GLOBAL.MESSAGE_LEVEL to '10' set GLOBAL.USER to upper(USER) set GLOBAL.COMPANY to OUT.PROC_GET_EMP_INIT.2.1 set GLOBAL.DIVN_CODE to OUT.PROC_GET_EMP_INIT.2.2 set GLOBAL.USER_NAME to OUT.PROC_GET_EMP_INIT.2.3 set GLOBAL.LAST_LOGIN to OUT.PROC_GET_EMP_INIT.2.4 set GLOBAL.IMPERS_USER to OUT.PROC_GET_EMP_INIT.2.5 set GLOBAL.STARTMENU to OUT.PROC_GET_EMP_INIT.2.6 set GLOBAL.USER_STATUS to OUT.PROC_GET_EMP_INIT.2.7 set GLOBAL.SMAN_CODE to OUT.PROC_GET_EMP_INIT.2.8 set GLOBAL.SUPERVISOR to OUT.PROC_GET_EMP_INIT.2.9 set GLOBAL.LOCATION to OUT.PROC_GET_EMP_INIT.2.10 set GLOBAL.ADMIN to OUT.PROC_GET_EMP_INIT.2.11 set GLOBAL.PRV_PASS to OUT.PROC_GET_EMP_INIT.2.12 set GLOBAL.EMP_CODE to OUT.PROC_GET_EMP_INIT.2.13 set GLOBAL.USER_SALT to OUT.PROC_GET_EMP_INIT.2.14 deny when is_blank(GLOBAL.COMPANY) else "Employee data not found." call PROC_GET_COMP_INIT(GLOBAL.COMPANY, GLOBAL.DIVN_CODE, null) set GLOBAL.COMPANY to OUT.PROC_GET_COMP_INIT.3.1 set GLOBAL.COMPANY_NAME to OUT.PROC_GET_COMP_INIT.3.2 set GLOBAL.DIVN_CODE to OUT.PROC_GET_COMP_INIT.3.3 set GLOBAL.DIVN_NAME to OUT.PROC_GET_COMP_INIT.3.4 set GLOBAL.COMPANY_GROUP to OUT.PROC_GET_COMP_INIT.3.5 set GLOBAL.BASECURRENCY to OUT.PROC_GET_COMP_INIT.3.6 set GLOBAL.AYEAR to OUT.PROC_GET_COMP_INIT.3.7 set GLOBAL.NXT_AYEAR to OUT.PROC_GET_COMP_INIT.3.8 set GLOBAL.PRV_AYEAR to OUT.PROC_GET_COMP_INIT.3.9 set GLOBAL.REP_HOST_NAME to OUT.PROC_GET_COMP_INIT.3.10 set GLOBAL.REP_PORT to OUT.PROC_GET_COMP_INIT.3.11 set GLOBAL.REP_SERVER to OUT.PROC_GET_COMP_INIT.3.12 set GLOBAL.NO_DAYS to OUT.PROC_GET_COMP_INIT.3.13 set GLOBAL.STK_CHK_TYPE to OUT.PROC_GET_COMP_INIT.3.14 set GLOBAL.EDT_DOC_DAYS to OUT.PROC_GET_COMP_INIT.3.15 set GLOBAL.DATETIME to OUT.PROC_GET_COMP_INIT.3.16 set GLOBAL.DATEFORMAT to OUT.PROC_GET_COMP_INIT.3.17 set GLOBAL.DATEYEARFORMAT to OUT.PROC_GET_COMP_INIT.3.18 set GLOBAL.CURR_DECIMAL to OUT.PROC_GET_COMP_INIT.3.19 set GLOBAL.CURR_FORMAT to OUT.PROC_GET_COMP_INIT.3.20 deny when is_blank(GLOBAL.COMPANY_NAME) else "Company data not found." call PROC_GET_INIT_DTL(GLOBAL.COMPANY, GLOBAL.AYEAR, null, null, null, null) set GLOBAL.AYEAR_FM to OUT.PROC_GET_INIT_DTL.4 set GLOBAL.AYEAR_TO to OUT.PROC_GET_INIT_DTL.5 set GLOBAL.AYEAR_STATUS to OUT.PROC_GET_INIT_DTL.6 set GLOBAL.MASTERPL to OUT.PROC_GET_INIT_DTL.3 set GLOBAL.MESSAGE_LEVEL to '10' # 1 statement did not convert.# line 73 # EXCEPTION # WHEN NO_DATA_FOUND THEN # MESSAGE('No data found for the given criteria.'); # Pause; # RAISE Form_Trigger_Failure; # WHEN OTHERS THEN # MESSAGE('Error in Assign_Global: ' || SQLERRM); # Pause; # # BEGIN # IF cur_emp IS NOT NULL THEN # CLOSE cur_emp; # END IF; # EXCEPTION WHEN OTHERS THEN NULL; # END; # BEGIN # IF cur_comp IS NOT NULL THEN # CLOSE cur_comp; # END IF; # EXCEPTION WHEN OTHERS THEN NULL; # END; # RAISE Form_Trigger_Failure; # reason: it handles NO_DATA_FOUND and OTHERS and re-raises, and CRL has no clause that runs when a statement fails: the error path ends the program either way, so the statements above it convert and the handler does not
46 clauses converted, 1 statement refused
5. fmb_loginon unit RESET_PASSstudy
What you havePROGRAM-UNIT
Procedure Reset_Pass Is
V_Mail Varchar2(100);
V_Text Varchar2(4000);
V_Pass Varchar2(100);
V_Sender Varchar2(100);
V_Alert Varchar2(100);
V_User_Code Varchar2(100);
V_User_Name Varchar2(100);
V_Pass_Enc Varchar2(100);
V_Salt Varchar2(100);
V_User_Status Varchar2(10);
V_Reset_Count Number;
V_Last_Reset Date;
Begin
If :User Is Null Or Trim(:User) = '' Then
Login_Message('Please enter your username or email address.');
Pause;
Return;
End If;
V_Alert := Show_Alert('LOGIN_ALERT_REQ');
If V_Alert <> Alert_Button1 Then
Go_Item('PASS');
Return;
End If;
Begin
Select User_Code, User_Name, User_Email, User_Salt, User_Status,
Nvl(User_Reset_Count, 0), User_Last_Reset
Into V_User_Code, V_User_Name, V_Mail, V_Salt, V_User_Status,
V_Reset_Count, V_Last_Reset
From M_User
Where (Lower(User_Code) = Lower(Trim(:User)) Or Lower(User_Email) = Lower(Trim(:User)))
And Nvl(User_Status, 'O') Not In ('C', 'L');
Exception
When No_Data_Found Then
Login_Message('If this account exists, a password reset email will be sent shortly.');
Pause;
Return;
When Too_Many_Rows Then
Login_Message('Multiple accounts found. Please contact support.');
Pause;
Return;
End;
If V_Last_Reset Is Not Null And V_Last_Reset > Sysdate - Interval '5' Minute Then
Login_Message('Password reset was already requested recently. Please wait 5 minutes before trying again.');
Pause;
Return;
End If;
If V_Last_Reset Is Not Null And Trunc(V_Last_Reset) = Trunc(Sysdate) And V_Reset_Count >= 3 Then
Login_Message('Maximum password reset attempts reached for today. Please contact support.');
Pause;
Return;
End If;
If V_Mail Is Null Then
Login_Message('No email address found for this account. Please contact support.');
Pause;
Return;
End If;
If V_User_Status = 'H' Then
Login_Message('Account is on hold. Please contact support.');
Pause;
Return;
End If;
Begin
V_Sender := Fn_Get_Sys_Param('SYS_EMAIL_SENDER');
If V_Sender Is Null Then
Login_Message('Email system not configured. Please contact support.');
Pause;
Return;
End If;
V_Pass := Fn_Get_Password;
V_Pass_Enc := Pkg_Encrypt.Hash(V_Pass, V_Salt);
-- ? Fixed UPDATE without audit columns
Update M_User
Set User_Temp_Pass = V_Pass_Enc,
User_Temp_Pass_Valid = Sysdate + Interval '30' Minute,
User_Status = Case
When Nvl(User_Status, 'O') = 'F' Then 'F'
Else 'T'
End,
User_Reset_Count = Case
When Trunc(Nvl(User_Last_Reset, Sysdate - 1)) = Trunc(Sysdate)
Then Nvl(User_Reset_Count, 0) + 1
Else 1
End,
User_Last_Reset = Sysdate
Where User_Code = V_User_Code;
Commit;
V_Text := '<!DOCTYPE html>' ||
'<html>' ||
'<head>' ||
'<meta charset="UTF-8">' ||
'<meta name="viewport" content="width=device-width, initial-scale=1.0">' ||
'<title>Password Reset Request</title>' ||
'<style>' ||
'body { font-family: Arial, sans-serif; background-color: #f3f4f6; margin: 0; padding: 0; }' ||
'.container { max-width: 600px; margin: 40px auto; background: #ffffff; border: 2px solid #0F68BF; border-radius: 12px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px 30px; }' ||
'.header { text-align: center; padding: 20px 0; border-bottom: 2px solid #0F68BF; }' ||
'.header h1 { font-size: 24px; color: #0F68BF; margin: 0; }' ||
'.content { margin: 20px 0; }' ||
'.content p { font-size: 16px; color: #333333; line-height: 1.5; }' ||
'.content p.highlight { font-size: 18px; font-weight: bold; color: #0F68BF; text-align: center; margin: 20px 0; background: #f0f8ff; padding: 15px; border-radius: 8px; }' ||
'.warning { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; }' ||
'.warning p { margin: 5px 0; color: #856404; }' ||
'.footer { text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e0e0e0; font-size: 14px; color: #888888; }' ||
'.footer a { color: #0F68BF; text-decoration: none; }' ||
'</style>' ||
'</head>' ||
'<body>' ||
'<div class="container">' ||
'<div class="header">' ||
'<h1>?? Password Reset Request</h1>' ||
'</div>' ||
'<div class="content">' ||
'<p>Dear <strong>' || V_User_Name || '</strong>,</p>' ||
'<p>A password reset was requested for your ERP account (<strong>' || V_User_Code || '</strong>) at <strong>' ||
To_Char(Sysdate, 'DD-MON-YYYY HH24:MI:SS') || '</strong>.</p>' ||
'<p>Your temporary password is:</p>' ||
'<p class="highlight">' || V_Pass || '</p>' ||
'<div class="warning">' ||
'<p><strong>?? Security Notice:</strong></p>' ||
'<p>• This temporary password is valid for <strong>30 minutes only</strong></p>' ||
'<p>• You will be required to change your password immediately after login</p>' ||
'<p>• Do not share this password with anyone</p>' ||
'</div>' ||
'<p><strong>If you did not request this password reset:</strong></p>' ||
'<p>Please contact IT support immediately at <a href="mailto:support@family.qa">support@family.qa</a> as your account may be compromised.</p>' ||
'</div>' ||
'<div class="footer">' ||
'<p>Thank you,<br><strong>IT Department</strong><br>Family Food Centre</p>' ||
'<p style="font-size: 12px; color: #aaa;">This is an automated message. Please do not reply to this email.</p>' ||
'</div>' ||
'</div>' ||
'</body>' ||
'</html>';
Proc_Send_Mail(V_Sender, V_Mail, 'Password Reset - Action Required', V_Text);
Login_Message('A password reset email has been sent. Please check your inbox.');
Pause;
:Pass := Null;
Go_Item('USER');
Exception
When Others Then
Rollback;
Login_Message('An error occurred during the password reset process. Please try again or contact support.'|| Sqlerrm);
Pause;
End;
Exception
When Others Then
Login_Message('Unexpected error: ' || Sqlerrm);
Pause;
End Reset_Pass;
/*
Procedure Reset_Pass Is
V_Mail Varchar2(100);
V_Text Varchar2(4000);
V_Pass Varchar2(100) := Fn_Get_Password;
V_Sender Varchar2(100) := Fn_Get_Sys_Param('SYS_EMAIL_SENDER');
V_Alert Varchar2(100) := Show_Alert('LOGIN_ALERT_REQ');
V_User_Code Varchar2(100);
V_User_Name Varchar2(100);
V_Pass_Enc Varchar2(100);
V_Salt VARCHAR2(100);
Begin
Select User_Code, User_Name, User_Email, User_Salt
Into V_User_Code, V_User_Name, V_Mail, V_Salt
From M_User
Where Lower(User_Code) = Lower(:User) Or Lower(User_Email) = Lower(:User);
If V_User_Code Is Not Null Then
If V_Alert = Alert_Button1 Then
Begin
V_Pass_Enc := Pkg_Encrypt.Hash(V_Pass, V_Salt);
-- ? Use status 'T' for temporary password instead of 'F'
Update M_User
Set User_Temp_Pass = V_Pass_Enc,
User_Temp_Pass_Valid = Sysdate + Interval '30' Minute,
User_Status = 'T' -- ? Temporary password status
Where Lower(User_Code) = Lower(V_User_Code) Or Lower(User_Email) = Lower(V_Mail)
And Nvl(User_Status, 'O') <> 'H';
Commit;
V_Text := '<!DOCTYPE html>' ||
'<html>' ||
'<head>' ||
'<meta charset="UTF-8">' ||
'<meta name="viewport" content="width=device-width, initial-scale=1.0">' ||
'<title>Password Reset Request</title>' ||
'<style>' ||
'body { font-family: Arial, sans-serif; background-color: #f3f4f6; margin: 0; padding: 0; }' ||
'.container { max-width: 600px; margin: 40px auto; background: #ffffff; border: 2px solid #0F68BF; border-radius: 12px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px 30px; }' ||
'.header { text-align: center; padding: 20px 0; border-bottom: 2px solid #0F68BF; }' ||
'.header h1 { font-size: 24px; color: #0F68BF; margin: 0; }' ||
'.content { margin: 20px 0; }' ||
'.content p { font-size: 16px; color: #333333; line-height: 1.5; }' ||
'.content p.highlight { font-size: 18px; font-weight: bold; color: #0F68BF; text-align: center; margin: 20px 0; }' ||
'.footer { text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e0e0e0; font-size: 14px; color: #888888; }' ||
'.footer a { color: #0F68BF; text-decoration: none; }' ||
'</style>' ||
'</head>' ||
'<body>' ||
'<div class="container">' ||
'<div class="header">' ||
'<h1>Password Reset Request</h1>' ||
'</div>' ||
'<div class="content">' ||
'<p>Dear <strong>' || V_User_Name || '</strong>,</p>' ||
'<p>You are receiving this email because a password reset request was made for your ERP account. Below is your temporary password:</p>' ||
'<p class="highlight">' || V_Pass || '</p>' ||
'<p>This temporary password is valid for <strong>30 minutes only</strong>. Please use it to log in and update your password immediately.</p>' ||
'<p>If you did not request this password reset, please ignore this email or contact support immediately.</p>' ||
'</div>' ||
'<div class="footer">' ||
'<p>Thank you,<br>The IT Department</p>' ||
'<p>If you have any questions, please contact us at <a href="mailto:support@family.qa">support@family.qa</a>.</p>' ||
'</div>' ||
'</div>' ||
'</body>' ||
'</html>';
Proc_Send_Mail(V_Sender, V_Mail, 'Forget Password', V_Text);
Login_Message('Thank you for your request. An email has been sent to you with a temporary password.');
Pause;
Exception
When Others Then
Login_Message('An error occurred during the password reset process. Please try again or contact support.');
Pause;
Rollback;
End;
Else
Go_Item('PASS');
End If;
End If;
Exception
When No_Data_Found Then
Login_Message('User not found. Please check your username or email.');
Pause;
When Others Then
Login_Message('Error: ' || Sqlerrm);
Pause;
End Reset_Pass;
*/What you getClause Rule Language
on unit RESET_PASS: # 1 statement did not convert.# Procedure Reset_Pass Is # V_Mail Varchar2(100); # V_Text Varchar2(4000); # V_Pass Varchar2(100); # V_Sender Varchar2(100); # V_Alert Varchar2(100); # V_User_Code Varchar2(100); # V_User_Name Varchar2(100); # V_Pass_Enc Varchar2(100); # V_Salt Varchar2(100); # V_User_Status Varchar2(10); # V_Reset_Count Number; # V_Last_Reset Date; # # Begin # If :User Is Null Or Trim(:User) = '' Then # Login_Message('Please enter your username or email address.'); # Pause; # Return; # End If; # # V_Alert := Show_Alert('LOGIN_ALERT_REQ'); # # If V_Alert <> Alert_Button1 Then # Go_Item('PASS'); # Return; # End If; # # Begin # Select User_Code, User_Name, User_Email, User_Salt, User_Status, # Nvl(User_Reset_Count, 0), User_Last_Reset # Into V_User_Code, V_User_Name, V_Mail, V_Salt, V_User_Status, # V_Reset_Count, V_Last_Reset # From M_User # Where (Lower(User_Code) = Lower(Trim(:User)) Or Lower(User_Email) = Lower(Trim(:User))) # And Nvl(User_Status, 'O') Not In ('C', 'L'); # Exception # When No_Data_Found Then # Login_Message('If this account exists, a password reset email will be sent shortly.'); # Pause; # Return; # When Too_Many_Rows Then # Login_Message('Multiple accounts found. Please contact support.'); # Pause; # Return; # End; # # If V_Last_Reset Is Not Null And V_Last_Reset > Sysdate - Interval '5' Minute Then # Login_Message('Password reset was already requested recently. Please wait 5 minutes before trying again.'); # Pause; # Return; # End If; # # If V_Last_Reset Is Not Null And Trunc(V_Last_Reset) = Trunc(Sysdate) And V_Reset_Count >= 3 Then # Login_Message('Maximum password reset attempts reached for today. Please contact support.'); # Pause; # Return; # End If; # # If V_Mail Is Null Then # Login_Message('No email address found for this account. Please contact support.'); # Pause; # Return; # End If; # # If V_User_Status = 'H' Then # Login_Message('Account is on hold. Please contact support.'); # Pause; # Return; # End If; # # Begin # V_Sender := Fn_Get_Sys_Param('SYS_EMAIL_SENDER'); # If V_Sender Is Null Then # Login_Message('Email system not configured. Please contact support.'); # Pause; # Return; # End If; # # V_Pass := Fn_Get_Password; # V_Pass_Enc := Pkg_Encrypt.Hash(V_Pass, V_Salt); # # -- ? Fixed UPDATE without audit columns # Update M_User # Set User_Temp_Pass = V_Pass_Enc, # User_Temp_Pass_Valid = Sysdate + Interval '30' Minute, # User_Status = Case # When Nvl(User_Status, 'O') = 'F' Then 'F' # Else 'T' # End, # User_Reset_Count = Case # When Trunc(Nvl(User_Last_Reset, Sysdate - 1)) = Trunc(Sysdate) # Then Nvl(User_Reset_Count, 0) + 1 # Else 1 # End, # User_Last_Reset = Sysdate # Where User_Code = V_User_Code; # # Commit; # # V_Text := '<!DOCTYPE html>' || # '<html>' || # '<head>' || # '<meta charset="UTF-8">' || # '<meta name="viewport" content="width=device-width, initial-scale=1.0">' || # '<title>Password Reset Request</title>' || # '<style>' || # 'body { font-family: Arial, sans-serif; background-color: #f3f4f6; margin: 0; padding: 0; }' || # '.container { max-width: 600px; margin: 40px auto; background: #ffffff; border: 2px solid #0F68BF; border-radius: 12px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px 30px; }' || # '.header { text-align: center; padding: 20px 0; border-bottom: 2px solid #0F68BF; }' || # '.header h1 { font-size: 24px; color: #0F68BF; margin: 0; }' || # '.content { margin: 20px 0; }' || # '.content p { font-size: 16px; color: #333333; line-height: 1.5; }' || # '.content p.highlight { font-size: 18px; font-weight: bold; color: #0F68BF; text-align: center; margin: 20px 0; background: #f0f8ff; padding: 15px; border-radius: 8px; }' || # '.warning { background: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; }' || # '.warning p { margin: 5px 0; color: #856404; }' || # '.footer { text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e0e0e0; font-size: 14px; color: #888888; }' || # '.footer a { color: #0F68BF; text-decoration: none; }' || # '</style>' || # '</head>' || # '<body>' || # '<div class="container">' || # '<div class="header">' || # '<h1>?? Password Reset Request</h1>' || # '</div>' || # '<div class="content">' || # '<p>Dear <strong>' || V_User_Name || '</strong>,</p>' || # '<p>A password reset was requested for your ERP account (<strong>' || V_User_Code || '</strong>) at <strong>' || # To_Char(Sysdate, 'DD-MON-YYYY HH24:MI:SS') || '</strong>.</p>' || # '<p>Your temporary password is:</p>' || # '<p class="highlight">' || V_Pass || '</p>' || # '<div class="warning">' || # '<p><strong>?? Security Notice:</strong></p>' || # '<p>• This temporary password is valid for <strong>30 minutes only</strong></p>' || # '<p>• You will be required to change your password immediately after login</p>' || # '<p>• Do not share this password with anyone</p>' || # '</div>' || # '<p><strong>If you did not request this password reset:</strong></p>' || # '<p>Please contact IT support immediately at <a href="mailto:support@family.qa">support@family.qa</a> as your account may be compromised.</p>' || # '</div>' || # '<div class="footer">' || # '<p>Thank you,<br><strong>IT Department</strong><br>Family Food Centre</p>' || # '<p style="font-size: 12px; color: #aaa;">This is an automated message. Please do not reply to this email.</p>' || # '</div>' || # '</div>' || # '</body>' || # '</html>'; # # Proc_Send_Mail(V_Sender, V_Mail, 'Password Reset - Action Required', V_Text); # # Login_Message('A password reset email has been sent. Please check your inbox.'); # Pause; # # :Pass := Null; # Go_Item('USER'); # # Exception # When Others Then # Rollback; # Login_Message('An error occurred during the password reset process. Please try again or contact support.'|| Sqlerrm); # Pause; # End; # # Exception # When Others Then # Login_Message('Unexpected error: ' || Sqlerrm); # Pause; # End Reset_Pass; # # # /* # Procedure Reset_Pass Is # V_Mail Varchar2(100); # V_Text Varchar2(4000); # V_Pass Varchar2(100) := Fn_Get_Password; # V_Sender Varchar2(100) := Fn_Get_Sys_Param('SYS_EMAIL_SENDER'); # V_Alert Varchar2(100) := Show_Alert('LOGIN_ALERT_REQ'); # V_User_Code Varchar2(100); # V_User_Name Varchar2(100); # V_Pass_Enc Varchar2(100); # V_Salt VARCHAR2(100); # # Begin # Select User_Code, User_Name, User_Email, User_Salt # Into V_User_Code, V_User_Name, V_Mail, V_Salt # From M_User # Where Lower(User_Code) = Lower(:User) Or Lower(User_Email) = Lower(:User); # # If V_User_Code Is Not Null Then # If V_Alert = Alert_Button1 Then # Begin # V_Pass_Enc := Pkg_Encrypt.Hash(V_Pass, V_Salt); # # -- ? Use status 'T' for temporary password instead of 'F' # Update M_User # Set User_Temp_Pass = V_Pass_Enc, # User_Temp_Pass_Valid = Sysdate + Interval '30' Minute, # User_Status = 'T' -- ? Temporary password status # Where Lower(User_Code) = Lower(V_User_Code) Or Lower(User_Email) = Lower(V_Mail) # And Nvl(User_Status, 'O') <> 'H'; # # Commit; # # V_Text := '<!DOCTYPE html>' || # '<html>' || # '<head>' || # '<meta charset="UTF-8">' || # '<meta name="viewport" content="width=device-width, initial-scale=1.0">' || # '<title>Password Reset Request</title>' || # '<style>' || # 'body { font-family: Arial, sans-serif; background-color: #f3f4f6; margin: 0; padding: 0; }' || # '.container { max-width: 600px; margin: 40px auto; background: #ffffff; border: 2px solid #0F68BF; border-radius: 12px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); padding: 20px 30px; }' || # '.header { text-align: center; padding: 20px 0; border-bottom: 2px solid #0F68BF; }' || # '.header h1 { font-size: 24px; color: #0F68BF; margin: 0; }' || # '.content { margin: 20px 0; }' || # '.content p { font-size: 16px; color: #333333; line-height: 1.5; }' || # '.content p.highlight { font-size: 18px; font-weight: bold; color: #0F68BF; text-align: center; margin: 20px 0; }' || # '.footer { text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid #e0e0e0; font-size: 14px; color: #888888; }' || # '.footer a { color: #0F68BF; text-decoration: none; }' || # '</style>' || # '</head>' || # '<body>' || # '<div class="container">' || # '<div class="header">' || # '<h1>Password Reset Request</h1>' || # '</div>' || # '<div class="content">' || # '<p>Dear <strong>' || V_User_Name || '</strong>,</p>' || # '<p>You are receiving this email because a password reset request was made for your ERP account. Below is your temporary password:</p>' || # '<p class="highlight">' || V_Pass || '</p>' || # '<p>This temporary password is valid for <strong>30 minutes only</strong>. Please use it to log in and update your password immediately.</p>' || # '<p>If you did not request this password reset, please ignore this email or contact support immediately.</p>' || # '</div>' || # '<div class="footer">' || # '<p>Thank you,<br>The IT Department</p>' || # '<p>If you have any questions, please contact us at <a href="mailto:support@family.qa">support@family.qa</a>.</p>' || # '</div>' || # '</div>' || # '</body>' || # '</html>'; # # Proc_Send_Mail(V_Sender, V_Mail, 'Forget Password', V_Text); # # Login_Message('Thank you for your request. An email has been sent to you with a temporary password.'); # Pause; # Exception # When Others Then # Login_Message('An error occurred during the password reset process. Please try again or contact support.'); # Pause; # Rollback; # End; # Else # Go_Item('PASS'); # End If; # End If; # # Exception # When No_Data_Found Then # Login_Message('User not found. Please check your username or email.'); # Pause; # When Others Then # Login_Message('Error: ' || Sqlerrm); # Pause; # End Reset_Pass; # */ # reason: it handles NO_DATA_FOUND and TOO_MANY_ROWS and recovers, writing a value or showing a message on the error path, so the statements above it do not mean what they would mean without it: CRL has no clause that runs when a statement fails
0 clauses converted, 1 statement refused