1

I am getting the Equipment/Service Level Detail Table values but it"s not proper order. Want to display X1,X2,X3,Y1,Y2,Y3....here displaying X1,X2,Y1,X3,Y2,Y3 in PDF , could you help me?

VF page :

<style type="text/css">
    .custPopup{
        background-color: white;
        border-width: 2px;
        border-style: solid;
        z-index: 9999;
        left: 50%;
        padding:1px;
        position: absolute;
        margin-left: -250px;
        top:100px;
    }
    .popupBackground{
        background-color:black;
        opacity: 0.20;
        filter: alpha(opacity = 20);
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        z-index: 9998;
    }

</style>

<apex:includeScript value="{!URLFOR($Resource.jQueryFiles, 'js/jquery-1.5.1.min.js')}" />
<script type="text/javascript">
    function doDone() {
        //alert('Test alert');
        $('#doneBtn').show('slow');
        $('#cancelBtn, #ppActionStatus').hide('slow');
        window.open('/{!q.Id}','_self' );
    }
</script>

<apex:sectionHeader title="Quote {!q.Name}" subtitle="Document Creation - Select Templates"/>
<div>
    <apex:outputPanel id="DocGenApplet-hover-link-panel"
        styleClass="my-hover-panel">
    </apex:outputPanel>
</div>
<apex:form id="frm">   
  <input type="hidden" id="pdfNames" value="{!fileNamesAsString}"/>
  <input type="hidden" id="templateIds" value="{!templateIdsAsString}"/>
  <input type="hidden" id="subreportIds" value="{!subreportIdsAsString}"/>
  <apex:pageMessages id="mess" showDetail="true" />

  <apex:pageBlock rendered="{!canbeEdited}">
    <apex:outputLabel style="font-weight:bold;padding-left:40%;font-size:120%;" value="Go To Step"></apex:outputLabel> 
    <apex:pageBlockButtons location="bottom">
        <apex:commandButton value="2"  style=" height:25px; width:30px; text-align:center;"
        action="{!qd_2}" title="Quote Details" />    
        <apex:commandButton value="3" style="height:25px;width:30px;text-align:center;"
        action="{!qd_3}" title="Contract Parameters"/>

        <apex:commandButton value="4" style="height:25px;9px;width:30px;text-align:center; "
        action="{!qd_4}" title="Select Equipment"/>    
        <apex:commandButton value="5" style="height:25px;width:30px;text-align:center ;"
        action="{!qd_5}" title="Select Services"/>    
        <apex:commandButton value="6" style="height:25px;9px;width:30px;text-align:center ;"
        action="{!qd_6}" title="Jobsite Variables"/>    
        <apex:commandButton value="7" style="height:25px;width:30px;text-align:center;"
        action="{!qd_7}" title="Add labor Mat’l & Sub"/>    
        <apex:commandButton value="8" style="height:25px;width:30px;text-align:center;;"
        action="{!qd_8}" title="Final Pricing"/>    
        <apex:commandButton value="9" style="height:25px;width:30px;text-align:center; color:red; background:yellow;"
        action="{!qd_9}" title="Create Doc"/>
    </apex:pageblockButtons> 
</apex:pageblock> 

<apex:pageBlock title="Templates">
    <apex:pageBlockButtons id="btns">
        <apex:commandButton value="Previous" status="bottomStatus"
                action="{!dg_previous}"
                title="Previous"/>
        <apex:commandButton value="Generate" action="{!generate}" status="stts" disabled="{!NOT(hasSelectedRecords)}" />
        <apex:commandButton value="Cancel" immediate="true" action="{!doCancel}"/>
        <apex:actionStatus startText="Please wait ..." id="stts" startStyle="color:red">
            <apex:facet name="start">
                   <apex:outputPanel style="color:red"> <img src="/img/loading.gif"/> Please wait ... </apex:outputPanel>                       
            </apex:facet>                 
        </apex:actionStatus>                    
    </apex:pageBlockButtons>

    <apex:pageBlockSection collapsible="false" columns="1" id="langTable" rendered="{!multiLanguage}">
        <apex:pageBlockSectionItem >
            <apex:selectList value="{!defaultLanguage}" size="1">                               
                <apex:selectOptions value="{!languages}"/> 
                <apex:actionSupport event="onchange"
                                    action="{!languageChange}" 
                                    rerender="frm"/>
            </apex:selectList>
            <apex:outputText value="Generated document will be attached to Notes And Attachments" rendered="{!isWordFormat}"/>
        </apex:pageBlockSectionItem>
    </apex:pageBlockSection>

    <apex:pageBlockTable value="{!templates}" var="t" id="pbTable">
        <apex:column headerValue="Select" style="width:40px;">
            <apex:facet name="header">
              <apex:inputCheckbox value="{!allChecked}" disabled="{!!hasEnabledRecords}"> 
                <apex:actionSupport event="onclick" 
                                    action="{!CheckAll}" 
                                    status="stts"
                                    rerender="frm, pbTable"/>
                <apex:actionSupport event="onchange" 
                                    action="{!CheckAll}" 
                                    status="stts"
                                    rerender="frm, pbTable"/>
              </apex:inputCheckbox>
            </apex:facet>

            <apex:inputCheckbox value="{!t.selected}" disabled="{!t.disabled}">
                <apex:actionSupport event="onclick" 
                                    action="{!updateOkBtn}" 
                                    status="stts"
                                    rerender="frm"/>
                <apex:actionSupport event="onchange" 
                                    action="{!updateOkBtn}" 
                                    status="stts"
                                    rerender="frm"/>
            </apex:inputCheckbox>               
        </apex:column>
        <apex:column headerValue="Name">
            <apex:outputPanel rendered="{!t.obj.Required__c}">
                <div class="requiredInput">
                    <div class="requiredBlock"></div>
                    <apex:outputText value="{!t.obj.Name}" style="{!t.style}"/>
                </div>
            </apex:outputPanel>
            <apex:outputText value="{!t.obj.Name}" style="{!t.style}"
                                rendered="{!NOT(t.obj.Required__c)}"/>
        </apex:column>
        <apex:column headerValue="Type">
            <apex:outputText value="{!t.obj.Type__c}" style="{!t.style}"/>              
        </apex:column>
        <apex:column headerValue="Status">
            <apex:outputText value="{!t.message}" style="{!t.style}"/>              
        </apex:column>
        <apex:column headerValue="Generated Date">
            <apex:outputText value="{!t.generatedDate}" style="{!t.style}"/>                
        </apex:column>
    </apex:pageBlockTable>

    <apex:pageBlockSection collapsible="false" columns="1" id="additionCbxTable">
        <apex:pageBlockSectionItem >
            <apex:selectList value="{!format}" size="1">                                
                <apex:selectOption itemValue="word" itemLabel="Word"/>  
                <apex:selectOption itemValue="pdf" itemLabel="PDF"/> 
                <apex:actionSupport event="onchange" 
                                    rerender="frm"/>
            </apex:selectList>
            <apex:outputText value="Generated document will be attached to Notes And Attachments" rendered="{!isWordFormat}"/>
        </apex:pageBlockSectionItem>
         <apex:pageBlockSectionItem >
            <apex:outputLabel value="Quote Last Modified Date"/>
            <apex:outputText value="{!quoteLastModifiedDate}"/>
         </apex:pageBlockSectionItem>
    </apex:pageBlockSection>  
</apex:pageBlock>

<apex:outputPanel id="tstpopup">
    <apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!showApplet}"/>
    <apex:outputPanel styleClass="custPopup" layout="block" rendered="{!showApplet}">
        <apex:pageBlock id="appletBlock">
            <apex:outputPanel layout="block" rendered="{!showApplet}" style="background-color: #ddb929; color:white; text; white-space:nowrap; font-weight:bold;">
                Please wait while document generator is working...                      
            </apex:outputPanel>
            <apex:outputPanel layout="block" style="text-align: center; margin: 10px;">

                <apex:actionStatus startText="Please wait ..." id="stts" startStyle="color:red">
                    <apex:facet name="start">
                        <apex:outputPanel style="color:red"> <img src="/img/loading.gif"/> Please wait ... </apex:outputPanel>                                                  
                    </apex:facet>                 
                </apex:actionStatus>                                                

                <applet id="docgenApplet" code = "com.salesoptimizer.sforce.applets.DocGenApplet" 
                        archive = "{!URLFOR($Resource.DocGenApplet, 'jrv.jar')},
                        {!URLFOR($Resource.DocGenJasper, 'jasperreports-4.1.2.jar')},           
                        {!URLFOR($Resource.DocGenJasper, 'commons-collections-2.1.1.jar')},         
                        {!URLFOR($Resource.DocGenJasper, 'commons-digester-1.7.jar')},
                        {!URLFOR($Resource.DocGenJasper, 'iText-2.1.7.jar')},       
                        {!URLFOR($Resource.DocGenJasper, 'commons-logging-1.0.4.jar')},
                        {!URLFOR($Resource.DocGenFonts, 'jasperreports-fonts-4.1.2.jar')}"
                        WIDTH = "490" HEIGHT = "60">
                    <param name="quoteId" value="{!q.id}"/>
                    <param name="quoteName" value="{!q.Name}"/>

                    <param name="pdfNames" value="{!fileNamesAsString}"/>
                    <param name="templateIds" value="{!templateIdsAsString}"/>
                    <param name="subreportIds" value="{!subreportIdsAsString}"/>

                    <param name="sessionId" value="{!$Api.Session_ID}"/>
                    <param name="partnerUrl" value="{!$Api.Partner_Server_URL_200}"/>
                    <param name="IMG_ROOT_DEFAULT" value="{!URLFOR($Resource.ABUMDocGenImages)}"/>
                    <param name="IMG_ROOT" value="{!IMG_ROOT}"/>
                    <param name="merge" value="{!mergeReports}"/>
                    <param name="overwrite" value="true"/>
                    <param name="saveAndEmailUrl" value="{!saveAndEmailUrl}"/>
                    <param name="docgenAction" value="{!abumAction}"/>
                    <param name="format" value="{!format}"/>
                    <param name="cache_option" value="no"/>
                     <param name="keepalive" value="true"/>
                </applet>
            </apex:outputPanel>

            <apex:outputPanel layout="block" style="text-align: center; margin: 10px; white-space:nowrap;">
                <span id="doneBtn" style="display: none;">
                    <apex:commandButton value="Ok, Close it"
                        title="Please click AFTER reports are generated"
                        action="{!doDonePopup}"
                        status="popstts"
                        immediate="true"
                    />
                </span>

                <span id="cancelBtn">
                    <apex:commandButton value="Cancel"
                        action="{!doCancelPopup}"
                        status="popstts"
                        immediate="true"
                    />
                </span>

                <span id="ppActionStatus" style="color:red">
                   <img src="/img/loading.gif"/> Please wait ...                                            
                </span>

            </apex:outputPanel>
        </apex:pageBlock>
    </apex:outputPanel>
 </apex:outputPanel>
</apex:form>
<apex:relatedList subject="{!Quote}" list="NotesAndAttachments"/>
<apex:relatedList subject="{!Quote}" list="QuoteDocuments"/>

Apex Controller :

public with sharing class SADocGenController {
private static String namespacePrefix = 'notset';
public String abumAction {get;set;}
public String format {get;set;}

public class DocGenTemplate
{
    public DGReport__c obj {get;set;}
    public Boolean selected {get;set;}
    public Boolean generated {get;set;}
    public String generatedDate {get;set;}
    public Boolean disabled {get;set;}
    public Boolean isOutdated {get;set;}
    public String message {get;set;}
    public String style {get;set;}
    public List<DGSubreport__c> subreports {get;set;}
}

public Quote q {get;set;}
public String quoteLastModifiedDate {set;get;}
public List<SelectOption> templateOptions {get;set;}

public String reportId {get;set;}
public List<DocGenTemplate> templates {get;set;}

public Boolean allChecked { get; set; }
public Boolean hasEnabledRecords { get; set; }
public Boolean hasSelectedRecords { get; set; }
public Boolean selectedOne { get; set; }
public Boolean hasMergedPdfGenerated { get; set; }
public Boolean canbeEdited{ get; set; }

public Boolean mergeReports { get; set; }
//public Boolean overwriteOld { get; set; }

public String mergeLabel { get; set; }
public String mergeStyle { get; set; }
public String IMG_ROOT {get;set; }
public String defaultLanguage {get;set; }
public Boolean multiLanguage { get; set; }
/*  Public boolean butn8_bool{get;set;}
public String buttntype{get;set;} */

public Boolean showApplet { get; set; }

public Boolean isWordFormat {
    get {
        return format == 'word';
    }
}
/*    public void cust_edit(){
   //Value= true;
   if(buttntype=='buttn9'){
       butn8_bool=false;
   }
}  */
public void checkAll() {
    Integer n = 0;
    for(DocGenTemplate dgt : templates){
        if (!dgt.disabled) {
            dgt.selected = allChecked;
        }
        if(dgt.selected) n++;

    }
    selectedOne = n == 1; 
    hasSelectedRecords = n > 0;    
}

public void languageChange() {
    loadTemplateOptions();
}  

public void updateOkBtn() {  
    Integer n = 0;
    for(DocGenTemplate dgt : templates){
        if (dgt.selected) {
            if(dgt.selected) n++;
        }
    }
    selectedOne = n == 1; 
    hasSelectedRecords = n > 0;
}

public List<SelectOption> getLanguages() {
    List<SelectOption> options = new List<SelectOption>();

    Schema.DescribeFieldResult fieldResult = DGReport__c.Language__c.getDescribe();
    List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();

    for( Schema.PicklistEntry f : ple) {
        options.add(new SelectOption(f.getLabel(), f.getValue()));
    }   
    return options;
}

public String getTemplateIdsAsString(){
    String tIds = '';
    for(DocGenTemplate dgt: templates)
        if(dgt.selected) {
            tIds += dgt.obj.DocumentId__c + ';';
        }
    return tIds;
}

/*Delimeter between subreports related to one report ':' between key and value '?'*/
public String getSubreportIdsAsString(){
    String srIds = '';
    for(DocGenTemplate dgt: templates)
        if(dgt.selected) {
            if (dgt.subreports.size() > 0) {
                for(DGSubreport__c dgp: dgt.subreports) {
                    srIds += '' + dgp.SubreportNumber__c + '?' + dgp.DocumentId__c + ':';
                }
            } else {
                srIds += 'NA';
            }
            srIds += ';';
        }
    return srIds;
}

public String getFileNamesAsString(){
    String tNames = '';
    for(DocGenTemplate dgt: templates)
        if(dgt.selected) {
            if (isWordFormat) {
                tNames += dgt.obj.FileName__c + '.docx;';
            } else {
                tNames += dgt.obj.FileName__c + '.pdf;';
            }
        }

    return tNames;
}

private Set<String> selectedTemplates = new Set<String>();

public SADocGenController(ApexPages.StandardController stdc) {
    this.templates = new List<DocGenTemplate>();
    this.templateOptions = new List<SelectOption>();        

    this.q = ABUMDAO.getQuote(stdc.getId());    
    this.quoteLastModifiedDate = q.lastModifiedDate.format();
    this.mergeReports = true;
    //this.overwriteOld = false;
    this.format = 'pdf';

    this.IMG_ROOT = '';
/*  buttntype=apexpages.currentpage().getparameters().get('buttntype');  */
    ABUM__c qs = ABUM__c.getInstance();
    if(qs != null) {
        this.IMG_ROOT = qs.IMG_ROOT__c;
        this.defaultLanguage = qs.DocGen_Default_Language__c;
        if (String.isBlank(this.defaultLanguage))
            this.defaultLanguage = 'English';
        this.multiLanguage = qs.DocGen_Multi_Language__c;
    }

}

public PageReference doCancel() {
    return new ApexPages.PageReference('/' + q.Id).setRedirect(true);
}

public PageReference doDonePopup() {
    showApplet = false;
    return new ApexPages.PageReference('/' + q.Id).setRedirect(true);
}

public PageReference doCancelPopup() {
    showApplet = false;
    return null;
}

public PageReference saveAndEmail() {
    this.abumAction = 'saveAndEmail';
    return generateImpl();
}

public PageReference generate() {
    this.abumAction = 'save';
    return generateImpl();
}

public String getSaveAndEmailUrl() {
    String urlStr = '/_ui/core/email/author/EmailAuthor?';

    if (q.ContactId != null) {
        urlStr += 'p2_lkid=' + q.ContactId
                    + '&'
                    + 'rtype=003'
                    + '&'
                    + 'p24=' + q.Contact.Email
                    + '&';

    }

    urlStr += 'p3_lkid=' + q.Id
            + '&'
            + 'retURL=%2F' + q.Id
            + '&'
            + 'doc_id=';

    return urlStr;
}

public PageReference generateImpl() {
    selectedTemplates.clear();
    Map<String, Integer> selectedTemplatesCounter = new Map<String, Integer>(); 
    for(DocGenTemplate dgt: templates) {
        if (dgt.selected) {
            Integer counter = 0;
            if (selectedTemplatesCounter.containsKey(dgt.obj.Type__c)) {
                counter = selectedTemplatesCounter.get(dgt.obj.Type__c);
            } 
            counter++;
            selectedTemplatesCounter.put(dgt.obj.Type__c, counter);
        }
        if(!dgt.selected && dgt.obj.Required__c) {
            ApexPages.addMessage(
                new ApexPages.Message(
                ApexPages.Severity.ERROR, 
                'Not all required documents are selected', 
                'Please select all reqired documents.'));
            return null;
        }
        if(dgt.selected) {
            selectedTemplates.add(dgt.obj.Id);
        }
    }

    //You can select any types of document templates but no more than one of each type
    String moreThanOneTypeSelectedMsg = '';
    Boolean moreThanOneTypeSelected = false;
    for (String key : selectedTemplatesCounter.keySet()) {
        if (selectedTemplatesCounter.get(key) > 1) {
            moreThanOneTypeSelectedMsg += key + ': ' + selectedTemplatesCounter.get(key);
            moreThanOneTypeSelected = true; 
        }
    }
    if (moreThanOneTypeSelected) {          
        ApexPages.addMessage(
            new ApexPages.Message(
            ApexPages.Severity.ERROR, 
            'Multiple documents of the same type (' + moreThanOneTypeSelectedMsg + ') have been selected', 
            'Please select no more than one document of each type.'));           
        return null;
    } 


    if (selectedTemplates.isEmpty()) {          
        ApexPages.addMessage(
            new ApexPages.Message(
            ApexPages.Severity.ERROR, 
            'Template is not selected', 
            'Please select some template.'));           
        return null;
    } 
    ApexPages.currentPage().getParameters().put('templateIds', getTemplateIdsAsString());
    showApplet = true;
    return null;//return Page.SADocGen;
}

private QuoteDocument findQuoteDocumentByName(String testStr,  List<QuoteDocument> atts) {
    for (QuoteDocument a : atts) {
        if (testStr == a.Name)
            return a;
    }
    return null;
}

private Boolean checkForOutdate(QuoteDocument tA) {
    return q.lastModifiedDate.getTime() > tA.CreatedDate.getTime();
}

public String calculateStyle(Boolean isDocGenerated, Boolean isDocOutdated) {
    String tStyle = '';
    if (isDocGenerated)
        tStyle += 'font-weight:bold;';
    if (isDocOutdated)
        tStyle += 'color: red;';
    return tStyle; 
} 

public void loadTemplateOptions() {
    templates.clear();
    templateOptions.clear();

    hasSelectedRecords = false;
    selectedOne = false;

    List<QuoteDocument> atts = [SELECT Id, Name, CreatedDate FROM QuoteDocument WHERE QuoteId =: q.Id];
    String qt_id=ApexPages.currentPage().getParameters().get('Id');
    if(qt_id!=null){
        Quote quot=[Select id,Approval_Status__c from Quote where id=:qt_id];
        if(quot.Approval_Status__c=='Approved'){
            canbeEdited=true;
        }
    }
    hasEnabledRecords = false;
    Double contractTerm = q.Escalation_Years__c;
    boolean checkedJobsites = [select count() From QuoteLineItem Where QuoteId = :q.id AND (Line_Type__c = 'Standard Job Site Variable' OR Line_Type__c = 'User Defined Job Site Variable')] > 0;
    for(DGReport__c dgto: [SELECT id, Name, Required__c, DocumentId__c, FileName__c, SortOrder__c, Type__c, Disabled__c, Checked_by_default__c,
                            (SELECT id, DocumentId__c, SubreportNumber__c from Subreports__r where Contract_Term__c = :contractTerm or Contract_Term__c = null) 
                             FROM DGReport__c
                             WHERE Language__c =: defaultLanguage and (Job_Type__c includes (:q.Job_Type__c) or Job_Type__c='') 
                                    and (Check_Jobsite_Variables__c = :checkedJobsites or Check_Jobsite_Variables__c = null) 
                             ORDER BY SortOrder__c LIMIT 100])
    {
            DocGenTemplate dgt = new DocGenTemplate();
            dgt.obj = dgto;
            dgt.disabled = dgto.Disabled__c;
            dgt.generated = false;
            dgt.isOutdated = false;
            dgt.style = '';

            QuoteDocument tA = findQuoteDocumentByName(dgto.FileName__c + '.pdf', atts); 
            if(tA != null) {
                dgt.message = 'Document generated';
                dgt.disabled = true;
                dgt.generated = true;
                dgt.generatedDate = tA.CreatedDate.format();
                dgt.isOutdated = checkForOutdate(tA);
                dgt.style = calculateStyle(dgt.generated, dgt.isOutdated);
            } else {
                dgt.message = 'Not generated';
                hasEnabledRecords = true;
            }
            dgt.selected = dgto.Checked_by_default__c;
            dgt.subreports = new List<DGSubreport__c>();
            for(DGSubreport__c dgp: dgto.Subreports__r)
            {
                dgt.subreports.add(dgp);
            }
            templates.add(dgt);
            SelectOption so = new SelectOption(dgto.Id, dgto.Name);
            templateOptions.add(so);
            if (dgt.selected == true) {
                    hasSelectedRecords = true;
            }
    }
}

public PageReference dg_previous() {
    PageReference pr = Page.SAFinalPricing;
    pr.getParameters().put('Id', q.Id);
    pr.setRedirect(true);
    return pr;
}


public PageReference qd_2() {
    PageReference pr = Page.SAQuoteDetails;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn2');
    pr.setRedirect(true);
    return pr;
}
public PageReference qd_3() {
    PageReference pr = Page.SAContractParams;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn3');
    pr.setRedirect(true);
    return pr;
}
public PageReference qd_4() {
    PageReference pr = Page.SAAddEquipment;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn4');
    pr.setRedirect(true);
    return pr;
}
public PageReference qd_5() {
    PageReference pr = Page.SAAddServices;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn5');
    pr.setRedirect(true);
    return pr;
}
public PageReference qd_6() {
    PageReference pr = Page.SAJobSite;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn6');
    pr.setRedirect(true);
    return pr;
}
public PageReference qd_7() {
    PageReference pr = Page.SAAdditional;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn7');
    pr.setRedirect(true);
    return pr;
}

public PageReference qd_8() {
    PageReference pr = Page.SAFinalPricing;
    pr.getParameters().put('Id', q.Id);
    pr.getParameters().put('buttntype', 'buttn8');
    pr.setRedirect(true);
    return pr;
}

 public PageReference qd_9(){
    return null;
 }
}
1
  • 1
    I tried to format you code but the formatting puts the content over the 30,000 character limits. Please cut down the Visualforce and Apex to the relevant sections and use the {} button to format those. – Keith C Aug 19 '14 at 10:17
1

I see a issues with what you've posted. Before trying to fix your existing code, I recommend you take a look at Best Practices for Rendering PDFs. I think you'll quickly discover that you're using certain Apex call outs in your code that are UNSAFE to use in a PDF.

It appears that you're attempting to render the PDF's in an <apex:outputPanel> using some kind of applet. I see where you have active content in that panel like <apex:actionStatus> (known to be UNSAFE) along with other <apex:CommandButton> callouts (also known to be UNSAFE) within additional nested <apex:outputPanels>. Any kind of active content can be problematic for the PDF render engine.

Without knowing exactly what your java applets are doing, I suspect there's little additional guidance anyone will be able to provide you with.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.