Intuit QBO Reports API -- What's the full qzurl URL? - rest

The documentation for the Intuit Partner Platform (IPP) QBO v3 API for reports (such as this one for a Balance Sheet) refers to very promising-looking elements called Quick-Zoom URLs (discussed near the bottom of the doc page I linked to).
When you run the report, you get an href element like this (redacted) one:
{u'href': u'ProfitAndLossDetail?token=PANDL_DET&parenttoken=PANDL&crit=accounttype%3D10..14%3Bhigh_date%3D03%2F31%2F2015%3Bnopost%3Dfalse%3Baccount%3Dmx%2C3%2C8%2C20%2C19%2C10%2C36%2C24%2C6%2C21%2C34%2C15%2C193%2C51%2C32%2C26%2C33163%2C77%2C62%2%2C86%2C107%2C60%2C79%2C166%%2C82%2C186%2C108%2C54%2C190%2C101%2C95%2C136%2C71%2C64%3Blow_date%3D01%2F01%2F2015%000740743&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName%2CKlass%2FOrderName', u'value': u'53.90'}
What's the full URL I'd construct to actually follow the link?
EDIT: To clarify, I am already able to run the balance sheet report with the qzurl links. What I need help with is building and following the Quick Zoom URLs themselves; the things in the response that are the qzruls...how do I follow those?

You can try all QBO V3 Reports using ApiExplorer.
https://developer.intuit.com/v2/apiexplorer?apiname=V3QBO#?id=Reports
If call these APIs programmatically please feel free to use IDG provided java/C#/php SDKs.
According docs,
Sandbox Base URL to use with development keys: https://sandbox-quickbooks.api.intuit.com/v3
Production Base URL to use with production keys: https://quickbooks.api.intuit.com/v3​
Operation: GET /company/companyId/reports/BalanceSheet?name=value[&...]
Edit Adding Request URL and response [ condition : qzurl=true ]
Request URI : https://quickbooks.api.intuit.com/v3/company/1368908040/reports/BalanceSheet?qzurl=true&requestid=3434534&minorversion=1&
Response -
<?xml version="1.0" encoding="UTF-8"?>
<Report xmlns="http://schema.intuit.com/finance/v3">
<Header>
<Time>2015-05-04T14:28:14-07:00</Time>
<ReportName>BalanceSheet</ReportName>
<ReportBasis>Accrual</ReportBasis>
<StartPeriod>2015-01-01</StartPeriod>
<EndPeriod>2015-05-05</EndPeriod>
<SummarizeColumnsBy>Total</SummarizeColumnsBy>
<Currency>INR</Currency>
<Option>
<Name>AccountingStandard</Name>
<Value>IFRS</Value>
</Option>
<Option>
<Name>NoReportData</Name>
<Value>false</Value>
</Option>
</Header>
<Columns>
<Column>
<ColTitle />
<ColType>Account</ColType>
</Column>
<Column>
<ColTitle>Total</ColTitle>
<ColType>Money</ColType>
</Column>
</Columns>
<Rows>
<Row type="Section" group="TotalAssets">
<Header>
<ColData value="Assets" />
<ColData value="" />
</Header>
<Rows>
<Row type="Section" group="OtherCurrentAssets">
<Header>
<ColData value="Current Assets" />
<ColData value="" />
</Header>
<Rows>
<Row type="Data">
<ColData value="Inventory Asset" id="83" />
<ColData value="0.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3Dmx%2C83%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Row>
<Row type="Section" group="AR">
<Header>
<ColData value="Accounts receivable (Debtors)" />
<ColData value="" />
</Header>
<Rows>
<Row type="Data">
<ColData value="Accounts Receivable (Debtors)" id="86" />
<ColData value="4299.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3Dmx%2C86%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Row>
</Rows>
<Summary>
<ColData value="Total Accounts receivable (Debtors)" />
<ColData value="4299.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3D86%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Summary>
</Row>
</Rows>
<Summary>
<ColData value="Total Current Assets" />
<ColData value="4299.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3D78%2C66%2C83%2C12%2C79%2C4%2C59%2C85%2C7%2C86%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Summary>
</Row>
</Rows>
<Summary>
<ColData value="Total Assets" />
<ColData value="4299.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3D78%2C66%2C83%2C12%2C79%2C4%2C59%2C85%2C7%2C86%2C5%2C6%2C8%2C10%2C11%2C13%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Summary>
</Row>
<Row type="Section" group="TotalLiabilitiesAndEquity">
<Header>
<ColData value="Liabilities and Equity" />
<ColData value="" />
</Header>
<Rows>
<Row type="Section" group="Equity">
<Header>
<ColData value="Equity" />
<ColData value="" />
</Header>
<Rows>
<Row type="Data">
<ColData value="Opening Balance Equity" id="84" />
<ColData value="0.00" href="QZReport?token=GENERIC_QZREPORT&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3Dmx%2C84%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Row>
<Row type="Data">
<ColData value="Retained Earnings" id="2" />
<ColData value="" />
</Row>
<Row type="Data" group="NetIncome">
<ColData value="Profit for the year" />
<ColData value="4299.00" href="ProfitAndLoss?token=PANDL&parenttoken=BAL_SHEET&crit=high_date%3D05%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3D*%3Blow_date%3D01%2F01%2F2015&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName" />
</Row>
</Rows>
<Summary>
<ColData value="Total Equity" />
<ColData value="4299.00" />
</Summary>
</Row>
</Rows>
<Summary>
<ColData value="Total Liabilities and Equity" />
<ColData value="4299.00" />
</Summary>
</Row>
</Rows>
</Report>
Edit -
Add the qzURL at then end of the following BASE URL and use OAuth tokens to call this endpoint.
For ex -
https://quickbooks.api.intuit.com/v3/company//reports/QZReport?token=GENERIC_QZREPORT&crit=high_date%3D07%2F05%2F2015%3Bnopost%3Dfalse%3Baccount%3Dmx%2C86%3Blow_date%3D01%2F01%2F2015&parenttoken=BAL_SHEET&cumulative=yes&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName

Assume the quickzoom url will be as follows-
"QZReport?token=GENERIC_QZREPORT&crit=high_date%3D07%2F14%2F2014%3Bnopost%3Dfalse%3Baccount%3Dmx%2C41%3Blow_date%3D01%2F01%2F2014&groupby=%28Account%2FAccountTypeID%2CAccount%2FOrderName"
1.Client will first send a request to know all the customization attributes supported for a QZReport .Request will also contain all the filtering criteria or attrobutes set.From above url the request will look like this.
https://quickbooks.api.intuit.com/v3/company/1368908040/customize?report=QZReport&high_date=07/14/2014&group_by=Acccount
Response of this request will be all customization attributes available for the QZReport or transaction report .
eg:{
reportName : "TranscationList"
params:
{
start_date:"",
end_date:"2014-07-14",
date_macro:"Today,YesterDay,ThisYear......"
account:"1,2,3,4,",
.... }
}

Related

Unsure how to fix the error in the Azure Devops Migration Tool for very old TFS collections

We've been asked to migrate some very old legacy projects (i.e. from TFS 2010 days) onto Azure Devops Services. These very old projects have almost nothing in their Process Configuration and only have one error line in the logs from the migration tool for all project types (Scrum, Agile, Basic etc...).
[Info #15:27:48.998] === Found 1 error(s) when compared against process TFS 2019 Update 1 Scrum ===
[Error #15:27:48.998] Custom processConfiguration typeField count '0' is different than system '8'.
[Info #15:27:48.998] === End of error(s) when compared against process TFS 2019 Update 1 Scrum ===
When looking at their Process Configuation it is only a few lines:
<?xml version="1.0" encoding="utf-16"?>
<ProjectProcessConfiguration>
<RequirementBacklog workItemCountLimit="1000">
<AddPanel />
</RequirementBacklog>
<TaskBacklog workItemCountLimit="1000">
<AddPanel />
</TaskBacklog>
<Properties>
<Property name="BugsBehavior" value="Off" />
</Properties>
</ProjectProcessConfiguration>
The only project that has no errors was a project added much later on TFS 2015:
<?xml version="1.0" encoding="utf-16"?>
<ProjectProcessConfiguration>
<BugWorkItems category="Microsoft.BugCategory" pluralName="Bugs" singularName="Bug">
<States>
<State type="Proposed" value="New" />
<State type="InProgress" value="Active" />
<State type="Complete" value="Closed" />
<State type="Resolved" value="Resolved" />
</States>
</BugWorkItems>
<FeedbackRequestWorkItems category="Microsoft.FeedbackRequestCategory" pluralName="Feedback Requests" singularName="Feedback Request">
<States>
<State type="InProgress" value="Active" />
<State type="Complete" value="Closed" />
</States>
</FeedbackRequestWorkItems>
<FeedbackResponseWorkItems category="Microsoft.FeedbackResponseCategory" pluralName="Feedback Responses" singularName="Feedback Response">
<States>
<State type="InProgress" value="Active" />
<State type="Complete" value="Closed" />
</States>
</FeedbackResponseWorkItems>
<PortfolioBacklogs>
<PortfolioBacklog category="Microsoft.EpicCategory" pluralName="Epics" singularName="Epic" workItemCountLimit="1000">
<AddPanel>
<Fields>
<Field refname="System.Title" />
</Fields>
</AddPanel>
<Columns>
<Column width="100" refname="System.WorkItemType" />
<Column width="400" refname="System.Title" />
<Column width="100" refname="System.State" />
<Column width="50" refname="Microsoft.VSTS.Scheduling.Effort" />
<Column width="50" refname="Microsoft.VSTS.Common.BusinessValue" />
<Column width="100" refname="Microsoft.VSTS.Common.ValueArea" />
<Column width="200" refname="System.Tags" />
</Columns>
<States>
<State type="Proposed" value="New" />
<State type="InProgress" value="Active" />
<State type="InProgress" value="Resolved" />
<State type="Complete" value="Closed" />
</States>
</PortfolioBacklog>
<PortfolioBacklog category="Microsoft.FeatureCategory" parent="Microsoft.EpicCategory" pluralName="Features" singularName="Feature" workItemCountLimit="1000">
<AddPanel>
<Fields>
<Field refname="System.Title" />
</Fields>
</AddPanel>
<Columns>
<Column width="100" refname="System.WorkItemType" />
<Column width="400" refname="System.Title" />
<Column width="100" refname="System.State" />
<Column width="50" refname="Microsoft.VSTS.Scheduling.Effort" />
<Column width="50" refname="Microsoft.VSTS.Common.BusinessValue" />
<Column width="100" refname="Microsoft.VSTS.Common.ValueArea" />
<Column width="200" refname="System.Tags" />
</Columns>
<States>
<State type="Proposed" value="New" />
<State type="InProgress" value="Active" />
<State type="InProgress" value="Resolved" />
<State type="Complete" value="Closed" />
</States>
</PortfolioBacklog>
</PortfolioBacklogs>
<RequirementBacklog category="Microsoft.RequirementCategory" parent="Microsoft.FeatureCategory" pluralName="Stories" singularName="User Story" workItemCountLimit="1000">
<AddPanel>
<Fields>
<Field refname="System.Title" />
</Fields>
</AddPanel>
<Columns>
<Column width="100" refname="System.WorkItemType" />
<Column width="400" refname="System.Title" />
<Column width="100" refname="System.State" />
<Column width="50" refname="Microsoft.VSTS.Scheduling.StoryPoints" />
<Column width="100" refname="Microsoft.VSTS.Common.ValueArea" />
<Column width="200" refname="System.IterationPath" />
<Column width="200" refname="System.Tags" />
</Columns>
<States>
<State type="Proposed" value="New" />
<State type="InProgress" value="Active" />
<State type="InProgress" value="Resolved" />
<State type="Complete" value="Closed" />
</States>
</RequirementBacklog>
<TaskBacklog category="Microsoft.TaskCategory" parent="Microsoft.RequirementCategory" pluralName="Tasks" singularName="Task" workItemCountLimit="1000">
<AddPanel>
<Fields>
<Field refname="System.Title" />
</Fields>
</AddPanel>
<Columns>
<Column width="400" refname="System.Title" />
<Column width="100" refname="System.State" />
<Column width="100" refname="System.AssignedTo" />
<Column width="50" refname="Microsoft.VSTS.Scheduling.RemainingWork" />
</Columns>
<States>
<State type="Proposed" value="New" />
<State type="InProgress" value="Active" />
<State type="Complete" value="Closed" />
</States>
</TaskBacklog>
<TypeFields>
<TypeField refname="Microsoft.VSTS.Common.Activity" type="Activity" />
<TypeField refname="Microsoft.VSTS.Common.StackRank" type="Order" />
<TypeField refname="Microsoft.VSTS.Feedback.ApplicationLaunchInstructions" type="ApplicationLaunchInstructions" />
<TypeField refname="Microsoft.VSTS.Feedback.ApplicationStartInformation" type="ApplicationStartInformation" />
<TypeField refname="Microsoft.VSTS.Feedback.ApplicationType" type="ApplicationType">
<TypeFieldValues>
<TypeFieldValue type="ClientApp" value="Client application" />
<TypeFieldValue type="RemoteMachine" value="Remote machine" />
<TypeFieldValue type="WebApp" value="Web application" />
</TypeFieldValues>
</TypeField>
<TypeField format="{0} h" refname="Microsoft.VSTS.Scheduling.RemainingWork" type="RemainingWork" />
<TypeField refname="Microsoft.VSTS.Scheduling.StoryPoints" type="Effort" />
<TypeField refname="System.AreaPath" type="Team" />
</TypeFields>
<Weekends>
<DayOfWeek>Sunday</DayOfWeek>
<DayOfWeek>Saturday</DayOfWeek>
</Weekends>
<Properties>
<Property name="HiddenBacklogs" value="Microsoft.EpicCategory" />
<Property name="BugsBehavior" value="AsTasks" />
</Properties>
<WorkItemColors>
<WorkItemColor primary="FFCC293D" secondary="FFFAEAE5" name="Bug" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Code Review Request" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Code Review Response" />
<WorkItemColor primary="FFFF7B00" secondary="FFFFD7B5" name="Epic" />
<WorkItemColor primary="FF773B93" secondary="FFEEE2F2" name="Feature" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Feedback Request" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Feedback Response" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Issue" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Shared Parameter" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Shared Steps" />
<WorkItemColor primary="FFF2CB1D" secondary="FFF6F5D2" name="Task" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Test Case" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Test Plan" />
<WorkItemColor primary="FFFF9D00" secondary="FFFCEECF" name="Test Suite" />
<WorkItemColor primary="FF009CCC" secondary="FFD6ECF2" name="User Story" />
</WorkItemColors>
</ProjectProcessConfiguration>
Anyone know of a easy way to fix the older projects? We want to import the code with changeset histories into Azure Devop Services and none of them have actually have work items (was managed externally on JIRA), build and release configs etc... We just want to get them onto the cloud to retire the legacy onpremise TFS servers (which are now running Azure Devops Server 2020.1.1 as per the migration suggestions).
Thanks for any help.
Edit: we're using TFS Team Project Manager from Jelle Druyts to help do some of the analysis, and am wondering if we can use the Transform function under Process Configuration to import the working projects config into the other projects.
Mark.
Sorry for the late reply on this. Since we didn't need to preserve templates and work items/ task history, we ended up abandoning full migrations. Ended up using the git-tfs (https://git-tfs.com/) tool to convert the TFS projects to a local git repository, then attaching that to a new Azure git project. Preserved all our history which was great.

How to handle selectedItem on hirarchy grid ZK

I got a problem with hirarchy grid, i am following this zk live demo,so i am using grid for header data and listbox for detail data, but when i am using the selectedItem property in listbox detail the second row detail become selected too,Here is my UI design
This is my code i am using mvvm
<grid model="#load(vm.headers )">
<columns>
<column width="40px" />
<column label="Nomor Part" sort="auto(name)" style="color:black"/>
<column label="Description" sort="auto(averageHigh)" align="center" style="color:black"/>
<column label="Hotline" sort="auto(averageVolume)" align="center" style="color:black"/>
</columns>
<template name="model" var="item" >
<row>
<custom-attributes details="${item.details}" hotline="${item.hotline}" partNumber="${item.partNumber}"/>
<detail open="false" fulfill="onOpen">
<!--<include src="/widgets/grid/hierarchy/season.zul" details="${details}" hotline="${item.hotline}"/>-->
<include src="/widgets/grid/hierarchy/season.zul" details="#bind(item.details)" hotline="#bind(item.hotline)" partNumber="#bind(item.partNumber)"/>
</detail>
<label value="${item.partNumber}" />
<label value="${item.partDescription}"/>
<checkbox checked="#bind(item.hotline)" onCheck="#command('checkHotline',hotline=item.hotline)"></checkbox>
</row>
</template>
</grid>
And here is my list detail code :
<vbox>
<listbox width="100%" height="300px" model="#load(details)" mold="paging" pageSize="5"
emptyMessage="no data found" >
<listhead style = "text-align: center">
<listheader label="Kode Dealer"/>
<listheader label="Nama Dealer"/>
<listheader label="Alamat"/>
<listheader label="Jarak"/>
<listheader label="Aksi"/>
</listhead>
<template name="model" var="dtl">
<listitem style = "text-align: center" >
<listcell label="#bind(dtl.dealerCode)"/>
<listcell label="#bind(dtl.dealerName)"/>
<listcell label="#bind(dtl.address)"/>
<listcell label="#bind(dtl.distance)"/>
<listcell>
<checkbox checked="#bind(dtl.selectedDealer)" oncheck="#command('onSelectDealer',partNumber)" visible="#load(not hotline)"/>
</listcell>
</listitem>
</template>
</listbox>
<div align="right">
<button label="Cancel" onClick="#command('onSelectDealer',partNumber=partNumber)"/>
</div>
</vbox>
It's hard to provide advice without seeing your code. I would pay careful attention to the row expander code (from the demo)
<!-- use custom-attributes to store quarters and stock in row,
so it can be accessed later when detail onOpen -->
<custom-attributes quarters="${each.quarters}" stock="${each}" />
<detail open="false" fulfill="onOpen">
<include src="/widgets/grid/hierarchy/season.zul"
stock="${stock}" quarters="${quarters}" />
</detail>

not able get the rows in the grid zk java

I have following code where I am adding the row to the group.
When I trying to fetch the rows by using grid.getRows.getChildren() is giving me the empty rows.
<template name="model">
<zk if="${forEachStatus.index == 0}">
<group label="refund" />
</zk>
<row if ="${forEachStatus.index != 0}">
<cell>
<inbox value="${forEachStatus.index}" />
</cell>
<cell>
<input value="${each}" />
</cell>
</row>
How we retrieve from the template.

PropelORM+PostgreSQL: How do I define an SQL-like CHECK constraint on a column in 'schema.xml'?

A little snippet of a database schema I'm trying to define in my "schema.xml" file:
<table name="hotelroom" phpName="hotelroom">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="room_number" type="varchar" size="10" required="true" />
<column name="price" type="numeric" defaultValue="1000" required="true" />
<unique>
<unique-column name="room_number" />
</unique>
</table>
In PostgreSQL for that "price" column I would've written CHECK (price > 0::numeric),but I can't seem to find any way to achieve this here.I've checked the documentation (http://propelorm.org/documentation/reference/schema.html), but couldn't find anything on this.
Thank you for the time.
You're using v1, but from the doc link above, looks like you're using v2,
I think you're looking for the GreaterThan which is only available from v2 onwards.
<behavior name="validate">
<parameter name="rule1" value="{column: price, validator: GreaterThan, options: {value: 0, message=Price is not valid}}" />
</behavior>

Cannot copy values from one Composite component to another JSF

I am having a pretty frustrating time trying to get values across components.
I am trying to do an address component that I can reuse, once for a residential address and once for a postal address. There is a selectOneCheck box which allows the user to specify that the residential address is the same as the postal address. I would like the the values of the first(residential address) component copied to the values of the second (postal address)component, then to disable the second component.
Here is my code for the composite component:
<composite:interface>
<composite:attribute name="addressLine1" required="true"
targets="addressLine1Text" />
<composite:attribute name="addressLine2" required="false"
targets="addressLine2Text" />
<composite:attribute name="addressLine3" required="false"
targets="addressLine3Text" />
<composite:attribute name="city" required="true" targets="cityText" />
<composite:attribute name="state" required="true" targets="stateText" />
<composite:attribute name="postCode" required="true"
targets="postCodeText" />
<composite:attribute name="styleClass" required="true" />
<composite:attribute name="disabled" required="true" />
<composite:attribute name="addressLine1Label" required="false"
targets="addressLine1Label" />
<composite:attribute name="addressLine2Label" required="false"
targets="addressLine2Label" />
<composite:attribute name="addressLine3Label" required="false"
targets="addressLine3Label" />
<composite:attribute name="cityLabel" required="false"
targets="cityLabel" />
<composite:attribute name="stateLabel" required="false"
targets="stateLabel" />
<composite:attribute name="postCodeLabel" required="false"
targets="postCodeLabel" />
<composite:implementation>
<composite:renderFacet name="heading"/>
<h:panelGrid columns="3">
<h:outputLabel id="addressLine1Label" for="addressLine1Text"
value="#{cc.attrs.addressLine1Label}" />
<h:inputText id="addressLine1Text" value="#{cc.attrs.addressLine1}" >
</h:inputText>
<h:message for="addressLine1Text" id="addressLine1Message" />
<h:outputLabel id="addressLine2Label" for="addressLine2Text"
value="#{cc.attrs.addressLine2Label}" />
<h:inputText id="addressLine2Text" value="#{cc.attrs.addressLine2}">
</h:inputText>
<h:message for="addressLine2Text" id="addressLine2Message" />
<h:outputLabel id="addressLine3Label" for="addressLine3Text"
value="#{cc.attrs.addressLine3Label}" />
<h:inputText id="addressLine3Text" value="#{cc.attrs.addressLine3}">
</h:inputText>
<h:message for="addressLine3Text" id="addressLine3Message" />
<h:outputLabel id="cityLabel" for="cityText"
value="#{cc.attrs.cityLabel}" />
<h:inputText id="cityText" value="#{cc.attrs.city}">
</h:inputText>
<h:message for="cityText" id="cityMessage" />
<h:outputLabel id="stateLabel" for="stateText"
value="#{cc.attrs.stateLabel}" />
<h:inputText id="stateText" value="#{cc.attrs.state}">
</h:inputText>
<h:message for="stateText" id="stateMessage" />
<h:outputLabel id="postCodeLabel" for="postCodeText"
value="#{cc.attrs.postCodeLabel}" />
<h:inputText id="postCodeText" value="#{cc.attrs.postCode}">
</h:inputText>
<h:message for="postCodeText" id="postCodeMessage" />
</h:panelGrid>
</composite:implementation>
Here is the the component in use :
<add:address
id="residentialAddress" styleClass="bold"
addressLine1="#{registrationBean.residentialAddress.addressLine1}"
addressLine2="#{registrationBean.residentialAddress.addressLine2}"
addressLine3="#{registrationBean.residentialAddress.addressLine3}"
city="#{registrationBean.residentialAddress.city}"
state="#{registrationBean.residentialAddress.state}"
postCode="#{registrationBean.residentialAddress.postCode}"
addressLine1Label="#{msgs.addressLine1}"
addressLine2Label="#{msgs.addressLine2}"
addressLine3Label="#{msgs.addressLine3}"
cityLabel="#{msgs.city}"
stateLabel="#{msgs.state}"
postCodeLabel="#{msgs.postCode}"
>
<f:facet name="heading">
<h:outputLabel value="#{msgs.residentialAddress}" />
</f:facet>
<f:converter for="add" converterId="myConvertor"/>
</add:address>
Here is the selectOneRadioButton:
<p:selectBooleanCheckbox
id="sameAsResidentialAddress"
itemLabel="#{msgs.sameAsResidentialAddress}"
valueChangeListener="#{registrationBean.sameAsResidentialAddress}"
>
<f:ajax execute="#form" render="postalAddress">
</f:ajax>
</p:selectBooleanCheckbox>
<h:message for="sameAsResidentialAddress"/>
Here is the component being resused for postal address:
<add:address id="postalAddress" styleClass="bold"
addressLine1="#{registrationBean.residentialAddress.addressLine1}"
addressLine2="#{registrationBean.postalAddress.addressLine2}"
addressLine3="#{registrationBean.postalAddress.addressLine3}"
city="#{registrationBean.postalAddress.city}"
state="#{registrationBean.postalAddress.state}"
postCode="#{registrationBean.postalAddress.postCode}"
addressLine1Label="#{msgs.addressLine1}"
addressLine2Label="#{msgs.addressLine2}"
addressLine3Label="#{msgs.addressLine3}" cityLabel="#{msgs.city}"
stateLabel="#{msgs.state}" postCodeLabel="#{msgs.postCode}"
rendered="#{!registrationBean.same}">
<f:facet name="heading">
<h:outputLabel value="#{msgs.postalAddress}" />
</f:facet>
<f:converter for="add" converterId="myConvertor"/>
</add:address>
The java code are a POJOs for Address and Registration. Registration has a valueChangeListener that sets a boolean to true if the sameAsResidentialAddress selectOneRadio is checked.
public void sameAsResidentialAddress(ValueChangeEvent event){
setSame((Boolean)event.getNewValue());
}
These components are on the same form named registration with no prepended id to them.
it roughly looks like this:
<h:form id="Registration">
<p:wizard>
<p:tab id ="address" title="Your Addresses">
<p:panel id="addresses">
<add:address id= "residentialAddress">
...
</add:address>
<p:selectBooleanCheckbox id="sameAsResidentialAddress">
...
</p:selectBooleanCheckbox>
<add:address id= "postalAddress">
...
</add:address>
</p:panel>
</p:tab>
</p:wizard>
</h:form>
I have tried my best to make my request as understandable as possible, and I hope you guys can understand what I am after. Please help me.
In the value change listener of the boolean check box you have to populate the postal address object which you are not doing. If both postal address and residential address are of the same type Address then you have to do
public void sameAsResidentialAddress(ValueChangeEvent event){
if((Boolean)event.getNewValue()) {
setSame((Boolean)event.getNewValue());
registrationBean.setPostalAddress(registrationBean.getResidentialAddress());
}
}
Hope this would help.
The problem was I did not completely understand the JSF lifecycle, I was updating my values the APPLY_REQUEST_VALUES phase instead of the INVOKE_APPLICATION phase. Also setting the postal address to the same object as the residential address is a bad idea because it end up with me not being able to update either one without affecting the other.
This works better.
public void sameAsResidentialAddress(ValueChangeEvent event) throws AbortProcessingException{
FacesContext context = FacesContext.getCurrentInstance();
if(context.getCurrentPhaseId() != PhaseId.INVOKE_APPLICATION){
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return;
}
if ((Boolean)event.getNewValue()){
this.setSame(true);
this.getPostalAddress().setAddressLine1(getResidentialAddress().getAddressLine1());
this.getPostalAddress().setAddressLine2(getResidentialAddress().getAddressLine2());
this.getPostalAddress().setAddressLine3(getResidentialAddress().getAddressLine3());
this.getPostalAddress().setCity(getResidentialAddress().getCity());
this.getPostalAddress().setState(getResidentialAddress().getState());
this.getPostalAddress().setPostCode(getResidentialAddress().getPostCode());
System.out.println("Value was true");
System.out.println("Postal Address " + getPostalAddress());
System.out.println("Residential Address " + getResidentialAddress());
}else{
setPostalAddress(new Address());
}
}