Pages

Thursday, November 27, 2025

ABC

<!DOCTYPE html>

<html>

<head>

<title>ABC</title>


<style>

body { font-family:"Segoe UI"; background:#e6eaef; margin:0; font-size:13px; }

.header { background:#2f4050; color:white; padding:8px 15px; }


.container { display:flex; padding:10px; gap:10px; }


.left {

  width:320px;

  background:white;

  border:1px solid #ccc;

  padding:10px;

}


.right {

  flex:1;

  background:white;

  border:1px solid #ccc;

  padding:10px;

}


.grid {

  display:grid;

  grid-template-columns:150px 1fr 150px 1fr;

  gap:6px 10px;

}


.section-title {

  grid-column: span 4;

  font-weight:bold;

  margin-top:10px;

  border-top:1px solid #ccc;

  padding-top:5px;

}


input, textarea {

  padding:4px;

  border:1px solid #999;

}


.officer-box input {

  width:180px;

}


textarea { height:45px; }


.actions {

  display: flex;

  flex-wrap: wrap;

  gap: 8px 10px;

}


.actions button {

  padding:6px 10px;

  background:#f1c40f;

  border:1px solid #b7950b;

}


button:hover { background:#d4ac0d; cursor:pointer; }


.output {

  width:100%;

  height:180px;

  margin-top:10px;

}


.officer-box {

  position:absolute;

  bottom:10px;

  right:10px;

  width:420px;

  background:#fff;

  border:1px solid #ccc;

  padding:8px;

}

.checklist-box {

  width: 340px;

  background: #fff;

  border: 1px solid #ccc;

  padding: 8px;

  margin-top: 10px; /* space from output box */


  display: grid;

  grid-template-columns: 1fr 1fr;

  gap: 6px 10px;

}



.checklist-box label {

  display: flex;

  align-items: center;

  gap: 5px;

}

table {

  width:100%;

  border-collapse:collapse;

}


th, td {

  border:1px solid #ccc;

  padding:4px;

  text-align:left;

}


table td input{

  width:50px;

}

</style>

</head>


<body>


<div class="header">ABC (App for Business Correspondence)</div>


<div class="container">


<div class="left">

<table id="countryTable"></table>

</div>


<div class="right">


<div class="grid">


<div class="section-title">CERTIFICATE OF RESIDENCY</div>


<label>Item # :</label><input id="item">

<label>BN:</label><input id="bn">


<label>Bus Name:</label>

<div style="display:flex; gap:6px;">

  <input id="busName" style="flex:1;">

  <button id="busNameToggle" style="padding:4px 6px;">ON</button>

</div>


<label>Mutual Fund Class:</label><input id="fundClass">


<label>Countries:</label><textarea id="countries"></textarea>

<label>Sanctioned Countries:</label><textarea id="sanctioned"></textarea>


<label>No Treaty Countries:</label><textarea id="noTreaty"></textarea>

<label>Date:</label><input type="date" id="date">


<label>Requestor:</label><input id="requestor">

<label>Pension Plan #:</label><input id="pension">


<label>Tax Year(s):</label><input id="taxYear">

<label>Batch #:</label><input id="batch">


<div class="section-title">VAT CERTIFICATE</div>


<label>Business Activity:</label><input id="activity">

<label>Reg. Effective Date:</label><input type="date" id="regDate">


<label>Today's Date:</label><input type="date" id="todayDate">


<label>Address:</label><textarea id="address"></textarea>


<div class="section-title"><b>GST ACCOUNT REGISTRATION</b></div>


<label>GST Backdate req. date:</label><input type="date" id="gstBackdate">

<label>Current GST Reg. date:</label><input type="date" id="gstCurrent">


</div>


<div class="actions">

<button onclick="generateNote()">Create Note</button>

<button onclick="generate()">Generate Cover Letter</button>

<!--<button onclick="generateMain()">Generate Main Letter</button>-->

<button onclick="generateLetter()">Generate Main Letter</button>

<button onclick="generateAppendix()">Generate Appendix A</button>

<button onclick="generateDenial()">Generate Denial Letter</button>

<button onclick="generateStatus()">Generate Certificate of Status</button>

<!--<button onclick="applyBulkCopies()">Copies #</button>-->

<button id="copyBtn" onclick="copyText()">Copy</button>

<button onclick="printBatchHeader()">Print Batch Header</button>

<!--<button onclick="resetForm()">Reset</button>-->

<button onclick="generateAuditReport()" class="ctis-btn">CTIS Audit Report</button>


</div>


<textarea id="output" class="output"></textarea>

<div class="checklist-box">


  <div style="grid-column: span 2;"><b>Checklist</b></div>


  <label><input type="checkbox" id="chk1"> Duplicates in CTIS?</label>

  <label><input type="checkbox" id="chk2"> Form Required?</label>


  <label><input type="checkbox" id="chk3"> Business Name Formatted?</label>

  <label><input type="checkbox" id="chk4"> TSAD ok?</label>


  <label><input type="checkbox" id="chk5"> Treaties/Sanctions Checked?</label>

  <label><input type="checkbox" id="chk6"> 3rd Party Address?</label>


</div>


</div>


</div>


<div class="officer-box">


<div style="display:flex; gap:10px; align-items:flex-start;">


  <div>

    <label>Officer:</label><br>

    <input id="officer"><br>


    <label>Job Title:</label><br>

    <input id="title"><br>


    <label>Cost Center:</label><br>

    <input id="costCenter"><br>

  </div>


  <div>

    <label>Phone #:</label><br>

    <input id="phone"><br>


    <label>Office Address:</label><br>

    <input id="officeAddress"><br>

  </div>


</div>


</div>



<script>


let countryData = {};

let busNameAutoFormat = true;

function resetCopyColor(){

  document.getElementById("copyBtn").style.background = "#f1c40f";

}


function formatDate(dateStr){

  if(!dateStr) return "";

  const [y,m,d] = dateStr.split("-");

  return new Date(y, m-1, d).toLocaleDateString("en-US", {

    year:"numeric", month:"long", day:"numeric"

  });

}


function toProperCase(str){

  return str.toLowerCase().replace(/\b\w+/g, function(word){

    if(word.length <= 3 && word === word.toUpperCase()) return word;

    if(word === "llp" || word === "gp") return word.toUpperCase();

    if(word === "inc") return "Inc";

    if(word === "ltd") return "Ltd";

    return word.charAt(0).toUpperCase() + word.slice(1);

  });

}


function cleanCountryList(text){

  let list = text.split(/,|\n/)

    .map(x=>x.trim())

    .filter(x=>x);


  list = list.map(x=>toProperCase(x));

  list = [...new Set(list)].sort();


  return list.join(", ");

}


function getNoTreatyList(){

  let list = noTreaty.value.split(/,|\n/)

    .map(x=>x.trim())

    .filter(x=>x)

    .map(x=>toProperCase(x));


  list = [...new Set(list)].sort();

  return list;

}


function updateNoTreatyTextbox(list){

  noTreaty.value = list.join(", ");

}


function processCountries(){

let list = countries.value.split(/,|\n/).map(x=>x.trim()).filter(x=>x);

countryData={};

list.forEach(c=>{

c = toProperCase(c);

countryData[c]={count:1, fund: fundClass.value};

});

renderTable();

}


function renderTable(){

let t = document.getElementById("countryTable");

t.innerHTML="";


let header = `

<tr>

<th>#</th>

<th>Countries</th>

<th>

  Copies 

  <input id="bulkCopiesInput" 

         type="number" 

         min="1" 

         style="width:50px; margin-left:6px;">

</th>

<th>Class</th>

</tr>`;

t.innerHTML += header;

setTimeout(() => {

  const bulkInput = document.getElementById("bulkCopiesInput");


  if (bulkInput) {

    bulkInput.addEventListener("input", function () {

      let val = parseInt(this.value);


      if (!val || val < 1) return;


      let table = document.getElementById("countryTable");


      // Update ALL rows

      for (let i = 1; i < table.rows.length; i++) {

        let input = table.rows[i].cells[2].querySelector("input");

        if (input) {

          input.value = val;

        }

      }


      // Sync internal data

      Object.keys(countryData).forEach(c => {

        countryData[c].count = val;

      });

    });

  }

}, 0);

let index = 1;


Object.keys(countryData).sort().forEach(c=>{

let row = `<tr>

<td>${index++}</td>

<td>${c}</td>

<td><input value="${countryData[c].count}" onchange="countryData['${c}'].count=this.value"></td>

<td><input value="${countryData[c].fund}" onchange="countryData['${c}'].fund=this.value"></td>

</tr>`;

t.innerHTML+=row;

});


let noTreatyList = getNoTreatyList();

noTreatyList.forEach(c=>{

  if(!countryData[c]){

    let row = `<tr>

<td>${index++}</td>

<td>${c}</td>

<td><input value="1"></td>

<td><input value="${fundClass.value}"></td>

</tr>`;

    t.innerHTML+=row;

  }

});

}


function getNextCountry(){

let keys = Object.keys(countryData).sort();

return keys.length ? keys[0] : null;

}


function removeOneCountry(c){

delete countryData[c];

updateCountriesTextbox();

renderTable();

}


function updateCountriesTextbox(){

countries.value = Object.keys(countryData).join(", ");

}


function generate(){

resetCopyColor();


// ===== CHECK TOTAL COPIES =====

let totalCopies = 0;


let table = document.getElementById("countryTable");


for(let i = 1; i < table.rows.length; i++){

  let input = table.rows[i].cells[2].querySelector("input");

  if(input){

    totalCopies += Number(input.value) || 0;

  }

}


if(totalCopies > 6){

  alert("Reminder: Total copies exceed 6. Please attach Envelope Cover Sheet.");

}


let countriesVal = countries.value.trim();

let noTreatyVal = noTreaty.value.trim();

let sanctionedVal = sanctioned.value.trim();


let itemVal = item.value;

let dateVal = formatDate(date.value);

let officerVal = officer.value;

let titleVal = title.value;


if(!countriesVal && !noTreatyVal){

output.value = `Dear Sir or Madam:


Subject: Request for certification of residency


Reference Number: I- ${itemVal}


We are replying to your request of ${dateVal}, asking us for certification of Canadian residency for income tax purposes.


We apologize for the delay in replying to your request.


If you require a Certificate of Residency for a specific country, we can provide one upon request once you provide the name of the country. Otherwise, please find the attached generic Certificate of Residency.


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours sincerely,





${officerVal}

${titleVal}

Enclosure(s)`;

return;

}


if(sanctionedVal){

let sancList = sanctionedVal.split(/,|\n/)

  .map(x=>x.trim())

  .filter(x=>x);


let sancString = sancList.join("\n");


output.value = `Dear Sir or Madam:


Subject: Request for certification of residency


Reference Number: I- ${itemVal}


We are replying to your request of ${dateVal}, asking us for certification of Canadian residency for income tax purposes.


We apologize for the delay in replying to your request.


You will find the certified form(s) and/or letter(s) attached.


The attached certificates of residency issued by Canada Revenue Agency are to certify that the holder of each certificate is a tax resident of Canada for the above tax year(s) for the purposes of the Income Tax Act and the tax treaty between Canada and the country indicated on the certificate, when such a treaty is in force.


Included in the attached documents are certificates for the following country or countries that are subject to economic sanctions:


${sancString}


It is the responsibility of each certificate holder to be aware of their obligations and to ensure their activities and investments are in compliance with Canadian law, including any sanctions as set out under the United Nations Act, the Special Economic Measures Act, and the Justice for Victims of Corrupt Foreign Officials Act and their regulations. Contravening sanctions is a criminal offence.


For more information, please consult the following webpage:

https://www.international.gc.ca/world-monde/international_relations-relations_internationales/sanctions/current-actuelles.aspx


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours sincerely,





${officerVal}

${titleVal}

Enclosure(s)`;

return;

}


if(!sanctionedVal && countriesVal){

output.value = `Dear Sir or Madam:


Subject: Request for certification of residency


Reference Number: I- ${itemVal}


We are replying to your request of ${dateVal}, asking us for certification of Canadian residency for income tax purposes.


We apologize for the delay in replying to your request.


You will find the certified form(s) and/or letter(s) attached.


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours sincerely,





${officerVal}

${titleVal}

Enclosure(s)`;

return;

}


output.value = "Unable to determine letter type.";

}


function generateMain(){

resetCopyColor();


let noTreatyList = getNoTreatyList();


if(noTreatyList.length){

  let c = noTreatyList[0];


  output.value =

`Subject: Certificate of Residency for ${c}


We are replying to your letter dated ${formatDate(date.value)}. This is to certify that ${busName.value} is a resident of Canada for tax year ${taxYear.value}.


Yours sincerely,





${officer.value}

${costCenter.value}

${title.value}`;


  noTreatyList.shift();

  updateNoTreatyTextbox(noTreatyList);

  renderTable();

  return;

}


let c = getNextCountry();


if(!c){

if(confirm("No countries left. Generate generic letter?")){

output.value = `Subject: Certificate of Residency


This is to certify that ${busName.value} is a resident of Canada for tax year ${taxYear.value}.


Yours sincerely,





${officer.value}

${costCenter.value}

${title.value}`;

}

return;

}


output.value =

`Subject: Certificate of Residency for ${c}


We are replying to your letter dated ${formatDate(date.value)}. This is to certify that ${busName.value} is a resident of Canada for tax year ${taxYear.value}.


Yours sincerely,





${officer.value}

${costCenter.value}

${title.value}`;


removeOneCountry(c);

}


function generateAppendix(){ resetCopyColor(); output.value="Appendix A Generated"; }

function generateDenial(){ resetCopyColor(); output.value="Denial Letter Generated"; }

function generateStatus(){ resetCopyColor(); output.value="Certificate of Status Generated"; }

function generateLetter(){


  resetCopyColor();


  // ===== VALUES =====

  let businessActivity = activity.value.trim();

  let pensionPlan = pension.value.trim();

  let mutualFundClass = fundClass.value.trim();

  let bnVal = bn.value.trim();


  let nameVal = busName.value.trim();

  let accountNumberVal = bn.value.trim();

  let taxYearVal = taxYear.value.trim();

  let itemVal = item.value.trim();

  let officerVal = officer.value.trim();

  let titleVal = title.value.trim();


  let noTreatyList = getNoTreatyList();


  // ===== PRIORITY RULES (EXIT EARLY) =====


  // A. Business Activity → Certificate of Status

  if(businessActivity){

    output.value = `Dear Sir or Madam:


Subject: Certificate of status`;

    return;

  }


  // B. Pension Plan

  if(pensionPlan){

    output.value = `Dear Sir or Madam:


Subject: Certificate of Canadian Residency and Tax exempt Status`;

    return;

  }


  // C. Mutual Fund

  if(mutualFundClass){

    output.value = `Dear Sir or Madam:


Subject: Certificate of Canadian Residency for Multiple Share Class Corporation`;

    return;

  }


  // D. BN RZ → Partnership

  if(bnVal.length >= 11 && bnVal.substring(9,11).toUpperCase() === "RZ"){

    output.value = `Dear Sir or Madam:


Subject: Certificate of Canadian Residency for Canadian Partnership with Appendix A`;

    return;

  }


  // ===== ONE-COUNTRY ENGINE =====


  // 1. NO TREATY FIRST

  if(noTreatyList.length){


    let c = noTreatyList[0];


    output.value = `Dear Sir or Madam:


Subject: Certification of Canadian residency


Name: ${nameVal}

Account Number: ${accountNumberVal}

Tax year(s): ${taxYearVal}

With respect to ${c}

Reference Number: ${itemVal}


This is to certify that, based on available information, ${nameVal} is considered a resident of Canada for income tax purposes for the above-noted tax year(s).


With this certification, foreign tax authorities may reduce or eliminate foreign tax on foreign income for a resident of Canada.


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours Sincerely,





${officerVal}

${titleVal}`;


    // remove used country

    noTreatyList.shift();

    updateNoTreatyTextbox(noTreatyList);

    renderTable();


    return;

  }


  // 2. NORMAL COUNTRIES

  let c = getNextCountry();


  if(!c){

    if(confirm("No countries left. Generate generic certificate?")){

      output.value = `Dear Sir or Madam:


Subject: Certification of Canadian residency


Name: ${nameVal}

Account Number: ${accountNumberVal}

Tax year(s): ${taxYearVal}

Reference Number: ${itemVal}


This is to certify that, based on available information, ${nameVal} is considered a resident of Canada for income tax purposes for the above-noted tax year(s).


With this certification, foreign tax authorities may reduce or eliminate foreign tax on foreign income for a resident of Canada.


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours Sincerely,





${officerVal}

${titleVal}`;

    }

    return;

  }


  output.value = `Dear Sir or Madam:


Subject: Certification of Canadian residency


Name: ${nameVal}

Account Number: ${accountNumberVal}

Tax year(s): ${taxYearVal}

Tax agreement between Canada and ${c}

Reference Number: ${itemVal}


This is to certify that, based on available information, ${nameVal} is considered a resident of Canada for income tax purposes for the above-noted tax year(s).


With this certification, foreign tax authorities may treat ${nameVal} as a resident of Canada for the purposes of Canada's tax treaties, including the Tax Convention between Canada and ${c}. This may reduce or eliminate foreign tax on foreign income for a resident of Canada.


We trust that this has fully addressed your enquiry. If not, you can use the available tools and information at canada.ca/taxes.


Yours Sincerely,





${officerVal}

${titleVal}`;


  // remove used country

  removeOneCountry(c);

}

/* ===== CTIS AUDIT ===== */


function getTodayString(){

  return new Date().toISOString().split("T")[0];

}


function getAuditLog(){

  return JSON.parse(localStorage.getItem("ctisAuditLog") || "[]");

}


function setAuditLog(log){

  localStorage.setItem("ctisAuditLog", JSON.stringify(log));

}


function addAuditLog(entry){

  let logs = getAuditLog();

  logs.push(entry);

  setAuditLog(logs);

}


function clearAuditLog(){

  localStorage.setItem("ctisAuditLog", JSON.stringify([]));

}


function autoResetAuditIfNewDay(){

  let today = getTodayString();

  let lastDate = localStorage.getItem("ctisAuditDate");


  if(lastDate !== today){

    clearAuditLog();

    localStorage.setItem("ctisAuditDate", today);

  }

}


function generateAuditReport(){


  let logs = getAuditLog();

  let officerName = document.getElementById("officer").value || "";

  let today = getTodayString();


  if(!logs.length){

    output.value = "No CTIS activity recorded for today.";

    return;

  }


  let report = `CTIS DAILY AUDIT REPORT

Date: ${today}

Officer: ${officerName}


`;


  let total = 0;


  logs.forEach(log=>{

    if(log.date === today){

      report += `Item ${log.item} → Countries: ${log.countries} → CTIS: ${log.ctis} → ${log.time}\n`;

      total += Number(log.ctis) || 0;

    }

  });


  report += `\n-----------------------------------\nTOTAL CTIS COPIES: ${total}`;


  output.value = report;

}

function generateNote(){

resetCopyColor();


let normalCountries = Object.keys(countryData);

let noTreatyList = getNoTreatyList();


let combined = [...new Set([...normalCountries, ...noTreatyList])].sort();


if(combined.length === 0){

output.value =

`BE Corr: Rec'd req. on ${date.value} from ${requestor.value} for a Generic CoR for year(s) ${taxYear.value} - Approved!`;

return;

}


let total = combined.length;

/* ===== CTIS LOGGING ===== */

let ctisCopies = total > 1 ? total - 1 : 0;


let now = new Date();

let time = now.toLocaleTimeString();


let existingLogs = getAuditLog();

let today = getTodayString();


let alreadyExists = existingLogs.some(log => 

  log.item === (item.value || "N/A") && log.date === today

);


if(!alreadyExists){

  addAuditLog({

    item: item.value || "N/A",

    countries: total,

    ctis: ctisCopies,

    time: time,

    date: today

  });

}


let table = document.getElementById("countryTable");


let details = combined.map(c => {

  let count = 1;


  for (let i = 1; i < table.rows.length; i++) {

    let rowCountry = table.rows[i].cells[1].innerText.trim();


    if (rowCountry === c) {

      let input = table.rows[i].cells[2].querySelector("input");

      count = Number(input.value) || 1;

      break;

    }

  }


  return `${c} (${count})`;

}).join(", ");


output.value =

`BE Corr: Rec'd req. on ${date.value} from ${requestor.value} for CoR for year(s) ${taxYear.value} for ${total} country(s) - Approved! [${details}]`;

}


function printBatchHeader(){

  let officerName = document.getElementById("officer").value || "";

  let contactNumber = document.getElementById("phone").value || "";

  let addressVal = document.getElementById("officeAddress").value || "";

  let program = "Business Enquiries Contact Centre Correspondence";


  let box = () => `

  <div class="box">

    <div class="title">Batch Header for outgoing lettermail</div>


    <div class="row"><span>Sending Program:</span><div class="line">${program}</div></div>

    <div class="row"><span>Contact Name:</span><div class="line">${officerName}</div></div>

    <div class="row"><span>Contact Number:</span><div class="line">${contactNumber}</div></div>

    <div class="row"><span>Building address/Floor number:</span><div class="line">${addressVal}</div></div>

    <div class="row"><span>Quantity in batch:</span><div class="line"></div></div>

  </div>

  `;


  let html = `

  <html>

  <head>

  <style>

    body { font-family:"Segoe UI"; padding:20px; }

    .grid { display:grid; grid-template-columns:1fr 1fr; gap:20px; }

    .box { border:1px solid black; padding:10px; height:220px; }

    .title { font-weight:bold; margin-bottom:10px; }

    .row { margin-bottom:8px; font-size:13px; }

    .line { border-bottom:1px solid black; height:16px; }

.ctis-btn {  background:#3498db; /* blue */  color:white;  font-weight:bold;}

.ctis-btn:hover {  background:#2e86c1;}

.ctis-btn {  margin-left:20px;}

  </style>

  </head>

  <body>

    <div class="grid">

      ${box()} ${box()} ${box()} ${box()}

    </div>

    <script>window.onload=function(){window.print();}<\/script>

  </body>

  </html>

  `;


  let win = window.open("", "", "width=900,height=700");

  win.document.write(html);

  win.document.close();

}


function copyText(){

navigator.clipboard.writeText(output.value);

document.getElementById("copyBtn").style.background = "green";

}


function applyBulkCopies(){


  let val = prompt("Enter number of copies:");


  if(val === null) return; // user cancelled


  val = parseInt(val);


  if(!val || val < 1){

    alert("Enter a valid number");

    return;

  }


  let table = document.getElementById("countryTable");


  // ✅ Update ALL table rows (including No Treaty)

  for(let i = 1; i < table.rows.length; i++){

    let input = table.rows[i].cells[2].querySelector("input");

    if(input){

      input.value = val;

    }

  }


  // ✅ Keep internal data in sync

  Object.keys(countryData).forEach(c=>{

    countryData[c].count = val;

  });

}


function resetForm(){

document.querySelectorAll("input, textarea").forEach(el=>el.value="");

countryData={};

renderTable();

resetCopyColor();

busNameAutoFormat = true;


  const btn = document.getElementById("busNameToggle");

  btn.textContent = "ON";

  btn.style.background = "#4CAF50";

}


item.addEventListener("blur", ()=>{

  let val = item.value.trim();

  if(val && !/^\d{8}$/.test(val)){

    alert("Item # must be exactly 8 digits");

    setTimeout(()=>{ item.value=""; }, 0);

  }

});


pension.addEventListener("blur", ()=>{

  let val = pension.value.trim();

  if(val && !/^\d{7}$/.test(val)){

    alert("Pension Plan # must be exactly 7 digits");

    setTimeout(()=>{ pension.value=""; }, 0);

  }

});


bn.addEventListener("blur", ()=>{

  let val = bn.value.trim();

  if(/^\d{9}$/.test(val)){

    bn.value = val + "RC0001";

  } else if(val && val.length !== 15){

    alert("BN must be 9 digits or 15 characters");

    setTimeout(()=>{ bn.value=""; }, 0);

  }

});


busName.addEventListener("blur", ()=> {

  if (busNameAutoFormat) {

    busName.value = toProperCase(busName.value);

  }

});


fundClass.addEventListener("blur", ()=> fundClass.value = toProperCase(fundClass.value));

activity.addEventListener("blur", ()=> activity.value = toProperCase(activity.value));

requestor.addEventListener("blur", ()=> requestor.value = toProperCase(requestor.value));

["date","todayDate","regDate","gstBackdate","gstCurrent"].forEach(id=>{

  document.getElementById(id).addEventListener("paste", function(e){

    e.preventDefault();


    let text = (e.clipboardData || window.clipboardData).getData("text").trim();

    let parsed = new Date(text);


    if(!isNaN(parsed)){

      let yyyy = parsed.getFullYear();

      let mm = String(parsed.getMonth()+1).padStart(2,'0');

      let dd = String(parsed.getDate()).padStart(2,'0');


      this.value = `${yyyy}-${mm}-${dd}`;

    } else {

      alert("Invalid date format");

    }

  });

});

["countries","sanctioned","noTreaty"].forEach(id=>{

  document.getElementById(id).addEventListener("blur", ()=>{

    let el = document.getElementById(id);

    el.value = cleanCountryList(el.value);


    if(id==="noTreaty"){

      let noTreatyList = getNoTreatyList();

      let countryList = countries.value.split(/,|\n/).map(x=>toProperCase(x.trim())).filter(x=>x);


      let filtered = countryList.filter(c=>!noTreatyList.includes(c));


      countries.value = [...new Set(filtered)].sort().join(", ");

      processCountries();

    }


    if(id==="countries") processCountries();

    if(id==="noTreaty") renderTable();

  });

});


address.addEventListener("focus", ()=>{

  if(!address.value.trim()){

    address.value = "Attn:\nC/O:\n";

  }

});


["officer","title","costCenter","phone","officeAddress"].forEach(id=>{

document.getElementById(id).addEventListener("input",()=>{

localStorage.setItem(id,document.getElementById(id).value);

});

});


window.onload=function(){

autoResetAuditIfNewDay();

["officer","title","costCenter","phone","officeAddress"].forEach(id=>{

document.getElementById(id).value = localStorage.getItem(id)||"";

});

document.getElementById("todayDate").value = new Date().toISOString().split("T")[0];

document.getElementById("busNameToggle").style.background = "#4CAF50";

};


countries.addEventListener("input", processCountries);

const busNameToggleBtn = document.getElementById("busNameToggle");


busNameToggleBtn.addEventListener("click", () => {

  busNameAutoFormat = !busNameAutoFormat;


  if (busNameAutoFormat) {

    busNameToggleBtn.textContent = "ON";

    busNameToggleBtn.style.background = "#4CAF50"; // green

  } else {

    busNameToggleBtn.textContent = "OFF";

    busNameToggleBtn.style.background = "#e74c3c"; // red

  }

});

</script>


</body>

</html>

Boar

 Public Sub TypeS_At_Row15_Col9()


    Dim terminal As Object


    On Error Resume Next

    'Attach directly to your open session by its name

    Set terminal = GetObject("Heron_E.rd3x")

    On Error GoTo 0


    If terminal Is Nothing Then

        MsgBox "Could not attach to session 'Heron_E.rd3x'.", vbExclamation

        Exit Sub

    End If


    'Send the S

    With terminal.Screen

        .MoveCursor 15, 9

        .SendKeys "S"

    End With


End Sub

Tortoi

Private Sub WriteToExistingSession()

    Dim app As Attachmate_Reflection_Objects_Framework.ApplicationObject

    Dim frame As Attachmate_Reflection_Objects.Frame

    Dim views As Object

    Dim view As Attachmate_Reflection_Objects.View

    Dim terminal As Attachmate_Reflection_Objects_Emulation_IbmHosts.IbmTerminal

    Dim scr As Attachmate_Reflection_Objects_Emulation_IbmHosts.IbmScreen

    Dim i As Integer

    Dim targetSession As String

    

    'Get existing Reflection Workspace

    On Error Resume Next

    Set app = GetObject("Reflection Workspace")

    On Error GoTo 0

    

    If app Is Nothing Then

        MsgBox "No Reflection Workspace found."

        Exit Sub

    End If

    

    Set frame = app.GetObject("Frame")

    frame.Visible = True

    

    'Look for session by tab title (change "mySavedSession" to your actual tab name)

    targetSession = "mySavedSession"  ' Or use full path to .rd3x file

    

    'Iterate ALL open views to find matching session

    For i = 1 To frame.ViewCount

        Set view = frame.View(i)

        

        'Match by tab title OR session file path

        If InStr(1, view.TitleText, targetSession) > 0 Or _

           InStr(1, view.FilePath, targetSession) > 0 Then

            

            Set terminal = view.Control

            Set scr = terminal.Screen

            

            'Wait for input ready

            scr.WaitForKeyboardEnabled 5000, 0

            

            'Write text

            scr.PutText2 "sam", 9, 5

            

            MsgBox "Text written to session: " & view.TitleText

            Exit Sub

        End If

    Next i

    

    MsgBox "Target session '" & targetSession & "' not found. Open views:"

    For i = 1 To frame.ViewCount

        Debug.Print "View " & i & ": " & frame.View(i).TitleText

    Next i

End Sub