Changeset 5664


Ignore:
Timestamp:
Jun 23, 2011, 11:53:05 AM (12 years ago)
Author:
Nicklas Nordborg
Message:

References #1153: Handling short read transcript sequence data

Updated web gui for extracts to handle the new parent item scheme. Some minor changes to the sample and physical bioassay gui also that among other things fixes some export issues.

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/clients/web/net/sf/basedb/clients/web/plugins/ItemQueryLoader.java

    r4900 r5664  
    3636  @base.modified $Date$
    3737*/
    38 public class ItemQueryLoader 
    39   implements DataLoader<BasicItem<?>>
     38public class ItemQueryLoader<T extends BasicItem>
     39  implements DataLoader<T>
    4040{
    4141  private final ItemQuery<?> query;
     
    5555
    5656  @Override
    57   public Object getData(ExportedProperty exportedProperty, BasicItem<?> item)
     57  public Object getData(ExportedProperty exportedProperty, T item)
    5858    throws Exception
    5959  {
  • trunk/src/clients/web/net/sf/basedb/clients/web/plugins/ParentBioMaterialLoader.java

    r5663 r5664  
    2424import net.sf.basedb.core.BioMaterial;
    2525import net.sf.basedb.core.DbControl;
    26 import net.sf.basedb.core.Include;
    2726import net.sf.basedb.core.ItemQuery;
    2827import net.sf.basedb.core.MeasuredBioMaterial;
     
    3635
    3736public class ParentBioMaterialLoader
    38   implements DataLoader<MeasuredBioMaterial<?>>
     37  extends ItemQueryLoader<MeasuredBioMaterial>
    3938{
    4039
    41   public ParentBioMaterialLoader()
    42   {}
     40  public ParentBioMaterialLoader(ItemQuery<? extends BioMaterial> query, String parameterName)
     41  {
     42    super(query, parameterName);
     43  }
    4344 
    44   @SuppressWarnings("unchecked")
    4545  @Override
    46   public Object getData(ExportedProperty exportedProperty, MeasuredBioMaterial<?> item)
     46  public Object getData(ExportedProperty exportedProperty, MeasuredBioMaterial item)
    4747    throws Exception
    4848  {
     
    5757      try
    5858      {
    59         parents = exportedProperty.propertyPath.getValue(dc, item);
     59        parents = item.getParent();
    6060      }
    6161      catch(Throwable e)
     
    6464    else
    6565    {
    66       ItemQuery<? extends BioMaterial> pooledQuery = item.getCreationEvent().getSources();
    67       pooledQuery.include(Include.ALL);
    68       parents = pooledQuery.list(dc);
     66      parents = super.getData(exportedProperty, item);
    6967    }
    7068    return parents;
  • trunk/www/biomaterials/extracts/edit_extract.jsp

    r5650 r5664  
    2929  import="net.sf.basedb.core.DbControl"
    3030  import="net.sf.basedb.core.Item"
     31  import="net.sf.basedb.core.Type"
    3132  import="net.sf.basedb.core.ItemContext"
    3233  import="net.sf.basedb.core.SystemItems"
     
    4849  import="net.sf.basedb.core.query.Orders"
    4950  import="net.sf.basedb.core.query.Hql"
     51  import="net.sf.basedb.core.query.Expressions"
     52  import="net.sf.basedb.core.query.Restrictions"
    5053  import="net.sf.basedb.clients.web.Base"
    5154  import="net.sf.basedb.clients.web.util.HTML"
     
    8184  BioMaterialEvent creationEvent = null;
    8285  Date eventDate = null;
    83   boolean isPooled = false;
     86  Item parentType = null;
    8487  boolean lockEventProperties = false;
    8588 
     
    144147    }
    145148    int sampleId = Values.getInt(request.getParameter("sample_id"));
     149    int extractId = Values.getInt(request.getParameter("extract_id"));
    146150    if (sampleId != 0)
    147151    {
    148152      currentSample  = Sample.getById(dc, sampleId);
    149       isPooled = false;
     153      parentType = Item.SAMPLE;
    150154      name = currentSample.getName() + ".e" + (currentSample.countExtracts() + 1);     
    151155    }
    152     else if(Values.getBoolean(request.getParameter("pooled")))
    153     {
    154       isPooled = true;
     156    else if (extractId != 0)
     157    {
     158      parentType = Item.EXTRACT;
     159      Extract e = Extract.getById(dc, extractId);
     160      name = e.getName() + ".e" + (e.countExtracts()+1);
     161      extractsQuery = Extract.getQuery();
     162      extractsQuery.restrict(Restrictions.eq(Hql.property("id"), Expressions.integer(extractId)));
     163    }
     164    else if (Values.getBoolean(request.getParameter("pooled")))
     165    {
     166      parentType = Item.EXTRACT;
    155167      name = Values.getString(cc.getPropertyValue("name"), "New pooled extract");
     168      extractsQuery = Extract.getQuery();
     169      extractsQuery.restrict(Restrictions.in(Hql.property("id"), Expressions.parameter("selected")));
     170      extractsQuery.setParameter("selected", cc.getSelected(), Type.INT);
    156171    }
    157172    else
    158173    {
    159       isPooled = Values.getBoolean(cc.getPropertyValue("pooled"));
    160174      name = Values.getString(cc.getPropertyValue("name"), "New extract");
    161175    }
     
    171185    creationEvent = extract.getCreationEvent();
    172186    eventDate = creationEvent.getEventDate();
    173     isPooled = extract.isPooled();
    174187    name = extract.getName();
    175188    lockEventProperties = !creationEvent.hasPermission(Permission.WRITE);
     
    205218    try
    206219    {
    207       currentSample = extract.getSample();
    208       if (currentSample != null) usedFromSample = creationEvent.getUsedQuantity(currentSample);
     220      if (parentType == Item.SAMPLE)
     221      {
     222        currentSample = (Sample)extract.getParent();
     223        if (currentSample != null)
     224        {
     225          usedFromSample = creationEvent.getUsedQuantity(currentSample);
     226        }
     227      }
    209228    }
    210229    catch (PermissionDeniedException ex)
     
    228247 
    229248    // Query to retrieve pooled extracts
    230     extractsQuery = (ItemQuery<Extract>)creationEvent.getSources();
    231     extractsQuery.include(Include.ALL);
    232     extractsQuery.order(Orders.asc(Hql.property("name")));
    233  
     249    if (parentType == Item.EXTRACT)
     250    {
     251      extractsQuery = (ItemQuery<Extract>)creationEvent.getSources();
     252    }
    234253  }
    235254 
     
    329348      var frm = document.forms['extract'];
    330349      var parents = new Array();
    331       if (frm.pooled[0].checked)
     350      if (frm.parentType[0].checked)
    332351      {
    333352        var sampleId = Math.abs(parseInt(frm.sample_id[frm.sample_id.selectedIndex].value));
     
    488507    }
    489508   
    490     function pooledOnClick()
    491     {
    492       var frm = document.forms['extract'];
    493       var isPooled = frm.pooled[1].checked;
    494       frm.sample_id.disabled = isPooled;
    495       frm.used_from_sample.disabled = isPooled;
    496       frm.extracts.disabled = !isPooled;
    497       frm.used_quantity.disabled = !isPooled;
     509    function parentTypeOnClick()
     510    {
     511      var frm = document.forms['extract'];
     512      var useExtracts = frm.parentType[1].checked;
     513      frm.sample_id.disabled = useExtracts;
     514      frm.used_from_sample.disabled = useExtracts;
     515      frm.extracts.disabled = !useExtracts;
     516      frm.used_quantity.disabled = !useExtracts;
    498517      parentsChanged = true;
    499518    }
     
    506525    {
    507526      var frm = document.forms['extract'];
    508       if (frm.pooled[1].checked)
    509       {
    510         alert('This is a pooled extract, which cannot have a sample as it\'s parent');
    511         return;
    512       }
    513527      var url = '../samples/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
    514528      url += '&callback=setSampleCallback&resetTemporary=1';
     
    532546      list[1].text = name;
    533547      list.selectedIndex = 1;
     548      frm.parentType[0].checked = true;
     549      frm.parentType[1].checked = false;
     550      parentTypeOnClick();
    534551      parentsChanged = true;
    535552    }
     
    538555    {
    539556      var frm = document.forms['extract'];
    540       if (!frm.pooled[1].checked)
    541       {
    542         alert('This is not a pooled extract');
    543         return;
    544       }
    545557      var url = 'index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectmultiple';
    546558      url += '&callback=addExtractCallback&resetTemporary=1';
     
    554566      if (!item) item = new Item('E', extractId, name+' [-]', '', '');
    555567      Link.addItem(document.forms['extract'].extracts, item);
     568      frm.parentType[0].checked = false;
     569      frm.parentType[1].checked = true;
     570      parentTypeOnClick();
    556571      parentsChanged = true;
    557572    }
     
    618633      initBioWell();     
    619634      initExtracts();
    620       pooledOnClick();
     635      parentTypeOnClick();
    621636    }
    622637    function initExtracts()
     
    624639      var extracts = document.forms['extract'].extracts;
    625640      <%
    626       if (extract != null && extract.isPooled())
    627       {
     641      if (extractsQuery != null)
     642      {
     643        extractsQuery.include(Include.ALL);
     644        extractsQuery.order(Orders.asc(Hql.property("name")));
    628645        ItemResultList<Extract> extracts = extractsQuery.list(dc);
    629646        for (Extract e : extracts)
    630647        {
    631           String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(e), -1);
    632           %>
    633           Link.addNewItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
    634           <%
    635         }
    636       }
    637       else if (extract == null && Values.getBoolean(request.getParameter("pooled")))
    638       {
    639         for (int eId : cc.getSelected())
    640         {
    641           Extract extractToPool = Extract.getById(dc, eId);
    642           %>
    643           Link.addItem(extracts, new Item('E', <%=extractToPool.getId()%>, '<%=HTML.javaScriptEncode(extractToPool.getName())%> [-]', '', ''));
    644           <%
     648          if (extract != null)
     649          {
     650            String usedQuantity = Values.formatNumber(creationEvent.getUsedQuantity(e), -1);
     651            %>
     652            Link.addNewItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [<%=usedQuantity%> µg]', '<%=usedQuantity%>'));
     653            <%
     654          }
     655          else
     656          {
     657            %>
     658            Link.addItem(extracts, new Item('E', <%=e.getId()%>, '<%=HTML.javaScriptEncode(e.getName())%> [-]', '', ''));
     659            <%
     660           
     661          }
    645662        }
    646663      }
     
    821838      <table class="form" cellspacing=0>
    822839      <tr>
    823         <td class="prompt">Pooled</td>
     840        <td class="prompt">Parent type</td>
    824841        <td>
    825           <input type="radio" name="pooled" value="0" onclick="pooledOnClick()"
    826             <%=!isPooled ? "checked" : ""%>
    827             >no
    828           <input type="radio" name="pooled" value="1" onclick="pooledOnClick()"
    829             <%=isPooled ? "checked" : ""%>
    830             >yes
     842          <input type="radio" name="parentType" id="parentType.sample"
     843            value="SAMPLE" onclick="parentTypeOnClick()"
     844            <%=parentType != Item.EXTRACT ? "checked" : ""%>
     845            ><label for="parentType.sample">Sample</label>
     846          <input type="radio" name="parentType" id="parentType.extract"
     847            value="EXTRACT" onclick="parentTypeOnClick()"
     848            <%=parentType == Item.EXTRACT ? "checked" : ""%>
     849            ><label for="parentType.extract">Extract</label>
    831850        </td>
    832851      </tr>
     
    837856            id="sample_id"
    838857            clazz="selectionlist"
     858            buttonstyle="width: 150px;"
     859            buttonicon="add.png"
     860            buttontitle="Select biosource&hellip;"
    839861            required="false"
    840862            current="<%=currentSample%>"
     
    846868            onchange="sampleOnChange()"
    847869          />
    848           Used
     870        </td>
     871      </tr>
     872      <tr>
     873        <td class="subprompt">-</td>
     874        <td>
     875          used quantity
    849876          <input <%=clazz%> type="text" name="used_from_sample" value="<%=Values.formatNumber(usedFromSample, -1)%>"
    850877            size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
     
    858885          <tr valign="top">
    859886          <td>
    860             <select name="extracts" size="5" multiple style="width: 20em;"
     887            <select name="extracts" size="5" multiple class="selectionlist"
    861888              onchange="extractsOnChange()">
    862             </select>&nbsp;<br>
    863             Used
    864             <input <%=clazz%> type="text" name="used_quantity" value=""
    865               size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
    866               onkeyup="usedQuantityOnBlur()"
    867             > (µg)
     889            </select>&nbsp;
    868890            <input type="hidden" name="modifiedExtracts" value="">
    869891            <input type="hidden" name="removedExtracts" value="">
    870892          </td>
    871893          <td>
    872             <table border="0">
    873             <tr><td width="150"><base:button
     894            <table border="0" cellspacing="0" cellpadding="0">
     895            <tr><td style="padding: 1px 0px 4px 0px;"><base:button
     896              style="width: 150px;"
    874897              onclick="addExtractsOnClick()"
    875898              title="Add&nbsp;extracts&hellip;"
     
    877900              /></td></tr>
    878901            <tr><td width="150"><base:button
     902              style="width: 150px;"
    879903              onclick="removeOnClick()"
    880904              title="Remove"
     
    887911        </td>
    888912      </tr>
     913      <tr>
     914        <td class="subprompt">-</td>
     915        <td>used quantity
     916        <input <%=clazz%> type="text" name="used_quantity" value=""
     917              size="12" maxlength="10" onkeypress="return Numbers.numberOnly(event)"
     918              onkeyup="usedQuantityOnBlur();"
     919            > (µg)
     920        </td>
     921      </tr>         
    889922      </table>
    890923    </t:tab>
  • trunk/www/biomaterials/extracts/index.jsp

    r5662 r5664  
    2424  @version 2.0
    2525--%>
    26 <%@page import="net.sf.basedb.core.BioMaterialEventSource"%>
    2726<%@ page pageEncoding="UTF-8" session="false"
    2827  import="net.sf.basedb.core.SessionControl"
     
    3332  import="net.sf.basedb.core.Extract"
    3433  import="net.sf.basedb.core.BioMaterialEvent"
     34  import="net.sf.basedb.core.BioMaterialEventSource"
    3535  import="net.sf.basedb.core.BioPlateEventType"
    3636  import="net.sf.basedb.core.BioWell"
     
    6161  import="net.sf.basedb.util.formatter.NameableFormatter"
    6262  import="net.sf.basedb.util.formatter.WellCoordinateFormatter"
     63  import="net.sf.basedb.util.formatter.ItemTypeFormatter"
    6364  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
    6465  import="net.sf.basedb.clients.web.plugins.ItemQueryLoader"
     
    8889    cc.setObject("export.formatter.bioWell.column", new WellCoordinateFormatter(false));
    8990    cc.setObject("export.formatter.&children(name)", new NameableFormatter());
    90     cc.setObject("export.formatter.&creationEvent.sourceBioMaterials(name)", new NameableFormatter());
    91     cc.setObject("export.formatter.&sourceEvents(event.physicalBioAssay.name)", new NameableFormatter());
    92     cc.setObject("export.formatter.&sourceEvents(event.bioMaterial.name)", new NameableFormatter());
    93    
     91    cc.setObject("export.formatter.&creationEvent.sources(bioMaterial.name)", new NameableFormatter());
     92    cc.setObject("export.formatter.&childCreationEvents(event.physicalBioAssay.name)", new NameableFormatter());
     93    cc.setObject("export.formatter.&childCreationEvents(event.bioMaterial.name)", new NameableFormatter());
     94    cc.setObject("export.formatter.parentType", new ItemTypeFormatter());
    9495   
    9596    String restrictionParameter = "extract";
     
    99100    bioAssayQuery.join(Hql.innerJoin("creationEvent", "ce"));
    100101    bioAssayQuery.join(Hql.innerJoin("ce", "sources", "src"));
    101     bioAssayQuery.restrict(Restrictions.eq(Hql.index("src", null), Expressions.parameter(restrictionParameter)));
     102    bioAssayQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Expressions.parameter(restrictionParameter)));
    102103    bioAssayQuery.order(Orders.asc(Hql.property("name")));
    103104    bioAssayQuery.include(cc.getInclude());
    104     cc.setObject("export.dataloader.&sourceEvents(event.physicalBioAssay.name)", new ItemQueryLoader(bioAssayQuery, restrictionParameter));
     105    cc.setObject("export.dataloader.&childCreationEvents(event.physicalBioAssay.name)", new ItemQueryLoader(bioAssayQuery, restrictionParameter));
    105106
    106107    // Child extracts
     
    108109    childExtractsQuery.join(Hql.innerJoin("creationEvent", "ce"));
    109110    childExtractsQuery.join(Hql.innerJoin("ce", "sources", "src"));
    110     childExtractsQuery.restrict(Restrictions.eq(Hql.index("src", null), Expressions.parameter(restrictionParameter)));
     111    childExtractsQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Expressions.parameter(restrictionParameter)));
    111112    childExtractsQuery.order(Orders.asc(Hql.property("name")));
    112113    childExtractsQuery.include(cc.getInclude());
    113     cc.setObject("export.dataloader.&sourceEvents(event.bioMaterial.name)", new ItemQueryLoader(childExtractsQuery, restrictionParameter));
     114    cc.setObject("export.dataloader.&childCreationEvents(event.bioMaterial.name)", new ItemQueryLoader(childExtractsQuery, restrictionParameter));
    114115   
    115     // Parent extracts
     116    // Parent items
    116117    final ItemQuery<Extract> parentExtractsQuery = Extract.getQuery();
    117     parentExtractsQuery.join(Hql.innerJoin("sourceEvents", "srcevt"));
    118     parentExtractsQuery.join(Hql.innerJoin("srcevt", "event", "evt"));
     118    parentExtractsQuery.join(Hql.innerJoin("childCreationEvents", "cce"));
     119    parentExtractsQuery.join(Hql.innerJoin("cce", "event", "evt"));
    119120    parentExtractsQuery.restrict(Restrictions.eq(Hql.property("evt", "bioMaterial"),  Expressions.parameter(restrictionParameter)));
    120121    parentExtractsQuery.order(Orders.asc(Hql.property("name")));
    121122    parentExtractsQuery.include(cc.getInclude());
    122     cc.setObject("export.dataloader.&creationEvent.sourceBioMaterials(name)", new ItemQueryLoader(parentExtractsQuery, restrictionParameter));
     123    cc.setObject("export.dataloader.&creationEvent.sources(bioMaterial.name)", new ParentBioMaterialLoader(parentExtractsQuery, restrictionParameter));
    123124  }
    124125%>
     
    277278 
    278279      // Parents tab
    279       extract.setPooled(Values.getBoolean(request.getParameter("pooled")));
    280       if (!extract.isPooled())
     280      Item parentType = Item.valueOf(request.getParameter("parentType"));
     281      if (parentType == Item.SAMPLE)
    281282      {
    282283        int sampleId = Values.getInt(request.getParameter("sample_id"), -1);
     
    284285        {
    285286          Sample s = sampleId == 0 ? null : Sample.getById(dc, sampleId);
    286           BioMaterialEventSource evtSrc = extract.setSample(s);
     287          BioMaterialEventSource evtSrc = creationEvent.setSource(s);
    287288          if (evtSrc != null)
    288289          {
     
    294295      else
    295296      {
     297        if (extract.getParentType() != Item.EXTRACT)
     298        {
     299          creationEvent.clearSources();
     300        }
    296301        String[] modifiedExtracts = Values.getString(request.getParameter("modifiedExtracts")).split(",");
    297302        for (int i = 0; i < modifiedExtracts.length; ++i)
  • trunk/www/biomaterials/extracts/list_extracts.jsp

    r5662 r5664  
    103103  final boolean createBioAssayPermission = sc.hasPermission(Permission.CREATE, Item.PHYSICALBIOASSAY);
    104104
     105  // Child bioassays
    105106  final ItemQuery<PhysicalBioAssay> bioAssayQuery = PhysicalBioAssay.getQuery();
    106107  bioAssayQuery.join(Hql.innerJoin("creationEvent", "ce"));
    107108  bioAssayQuery.join(Hql.innerJoin("ce", "sources", "src"));
    108   bioAssayQuery.restrict(Restrictions.eq(Hql.index("src", null), Hql.entityParameter("extract", Item.EXTRACT)));
     109  bioAssayQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Hql.entityParameter("extract", Item.EXTRACT)));
    109110  bioAssayQuery.order(Orders.asc(Hql.property("name")));
    110111  bioAssayQuery.include(cc.getInclude());
    111112
     113  // Child extracts
    112114  final ItemQuery<Extract> childExtractsQuery = Extract.getQuery();
    113115  childExtractsQuery.join(Hql.innerJoin("creationEvent", "ce"));
    114116  childExtractsQuery.join(Hql.innerJoin("ce", "sources", "src"));
    115   childExtractsQuery.restrict(Restrictions.eq(Hql.index("src", null), Hql.entityParameter("extract", Item.EXTRACT)));
     117  childExtractsQuery.restrict(Restrictions.eq(Hql.property("src", "bioMaterial"), Hql.entityParameter("extract", Item.EXTRACT)));
    116118  childExtractsQuery.order(Orders.asc(Hql.property("name")));
    117119  childExtractsQuery.include(cc.getInclude());
    118120 
     121  // Parent extracts
    119122  final ItemQuery<Extract> parentExtractsQuery = Extract.getQuery();
    120123  parentExtractsQuery.join(Hql.innerJoin("childCreationEvents", "cce"));
     
    173176      Table.poolItems(submitPage, '<%=ID%>', formId, '<%=itemType.name()%>', 'NewPhysicalBioAssay');
    174177    }
     178    function newExtract(extractId)
     179    {
     180      Main.viewOrEditItem('<%=ID%>', 'EXTRACT', 0, true, '&extract_id='+extractId);
     181    }
    175182    function editItem(itemId)
    176183    {
     
    377384        formatter="<%=dateFormatter%>"
    378385      />
    379       <tbl:columndef
    380         id="pooled"
    381         property="pooled"
    382         datatype="boolean"
    383         title="Pooled"
    384         sortable="true"
    385         filterable="true"
    386         exportable="true"
    387       />
     386      <%
     387      Enumeration<String, String> parentTypes = new Enumeration<String, String>();
     388      parentTypes.add(Integer.toString(Item.SAMPLE.getValue()), Item.SAMPLE.toString());
     389      parentTypes.add(Integer.toString(Item.EXTRACT.getValue()), Item.EXTRACT.toString());
     390      %>
    388391      <tbl:columndef
    389         id="sample"
    390         title="Sample"
    391         property="parent.name"
    392         datatype="string"
    393         sortable="true"
    394         filterable="true"
    395         exportable="true"
     392        id="parentType"
     393        title="Parent type"
     394        property="parentType"
     395        enumeration="<%=parentTypes%>"
     396        datatype="int"
     397        filterable="true"
     398        exportable="true"
     399        sortable="true"
    396400      />
    397401      <tbl:columndef
    398402        id="parents"
    399         title="Parent extracts"
     403        title="Parent items"
    400404        property="&creationEvent.sources(bioMaterial.name)"
     405        sortproperty="parent.name"
    401406        datatype="string"
    402407        filterable="true"
    403408        exportable="true"
     409        sortable="true"
    404410      />
    405411      <tbl:columndef
     
    662668            {
    663669              Extract item = extracts.next();
     670              Item parentType = item.getParentType();
    664671              BioMaterialEvent creationEvent = item.getCreationEvent();
    665672              int itemId = item.getId();
     
    727734                <tbl:cell column="originalQuantity"><%=Values.formatNumber(item.getOriginalQuantity(), 2)%></tbl:cell>
    728735                <tbl:cell column="remainingQuantity"><%=Values.formatNumber(item.getRemainingQuantity(), 2)%></tbl:cell>
    729                 <tbl:cell column="pooled"><%=item.isPooled()%></tbl:cell>
    730736                <tbl:cell column="protocol"
    731737                  ><base:propertyvalue
     
    737743                <tbl:cell column="eventDate" value="<%=creationEvent.getEventDate()%>" />
    738744                <tbl:cell column="entryDate" value="<%=creationEvent.getEntryDate()%>" />
    739                 <tbl:cell column="sample"><base:propertyvalue item="<%=item%>" property="parent"/></tbl:cell>
     745                <tbl:cell column="parentType"><%=parentType == null ? "" : parentType.toString() %></tbl:cell>
    740746                <tbl:cell column="parents">
    741747                  <%
    742                   if (item.isPooled())
     748                  if (item.hasSingleParent() || item.getParentType() == null)
     749                  {
     750                    %>
     751                    <base:propertyvalue item="<%=item%>" property="parent"/>
     752                    <%
     753                  }
     754                  else
    743755                  {
    744756                    String separator = "";
     
    759771                  }
    760772                  %>
     773                  <%=parentType != null ? "<span class=\"itemtype\">(" + parentType + ")</span>" : "" %>
    761774                </tbl:cell>
    762775                <tbl:cell column="children">
     
    778791                  }
    779792                  %>
     793                  <base:icon
     794                    image="add.png"
     795                    onclick="<%="newExtract("+itemId+")"%>"
     796                    tooltip="Create new child extract"
     797                    visible="<%=mode.hasEditLink() && createPermission && usePermission %>"
     798                  />
    780799                </tbl:cell>
    781800                <tbl:cell column="physicalBioAssays">
  • trunk/www/biomaterials/extracts/view_extract.jsp

    r5648 r5664  
    3030  import="net.sf.basedb.core.Group"
    3131  import="net.sf.basedb.core.Item"
     32  import="net.sf.basedb.core.CommonItem"
    3233  import="net.sf.basedb.core.ItemContext"
    3334  import="net.sf.basedb.core.ItemProxy"
     
    3637  import="net.sf.basedb.core.PhysicalBioAssay"
    3738  import="net.sf.basedb.core.Sample"
     39  import="net.sf.basedb.core.BioMaterial"
    3840  import="net.sf.basedb.core.BioMaterialEvent"
     41  import="net.sf.basedb.core.BioMaterialEventSource"
    3942  import="net.sf.basedb.core.BioWell"
    4043  import="net.sf.basedb.core.MultiPermissions"
     
    4447  import="net.sf.basedb.core.ItemQuery"
    4548  import="net.sf.basedb.core.ItemResultList"
     49  import="net.sf.basedb.core.SpecialQuery"
    4650  import="net.sf.basedb.core.Include"
     51  import="net.sf.basedb.core.query.ResultList"
    4752  import="net.sf.basedb.core.query.Orders"
    4853  import="net.sf.basedb.core.query.Hql"
     
    124129      Main.viewOrEditItem('<%=ID%>', '<%=itemType.name()%>', <%=itemId%>, true);
    125130    }
     131    function newExtract()
     132    {
     133      Main.viewOrEditItem('<%=ID%>', 'EXTRACT', 0, true, '&extract_id=<%=itemId%>');
     134    }
    126135    function shareItem()
    127136    {
     
    230239        title="Set owner&hellip;"
    231240        tooltip="<%=setOwnerPermission ? "Change owner of this item" : "You do not have permission to change ownership of this item"%>"
     241      />
     242      <tbl:button
     243        image="add.png"
     244        onclick="newExtract()"
     245        title="New child extract&hellip;"
     246        tooltip="Create a new child extract from this extract"
     247        visible="<%=sc.hasPermission(Permission.CREATE, Item.EXTRACT) && usePermission%>"
    232248      />
    233249      <tbl:button
     
    311327        <td><%=dateFormatter.format(creationEvent.getEntryDate())%></td>
    312328      </tr>
    313       <%
    314       if (!extract.isPooled())
    315       {
    316         %>
    317         <tr>
    318           <td class="prompt">Sample</td>
    319           <td><base:propertyvalue item="<%=extract%>" property="parent"/>
    320             <%
    321             try
    322             {
    323             %>
    324               <%=extract.getSample() != null ? "(" + Values.formatNumber(creationEvent.getUsedQuantity(extract.getSample()), 2, " µg") + ")" : ""%>
    325             <%
    326             }
    327             catch (PermissionDeniedException ex)
    328             {}
    329             %> 
    330 
    331           </td>
    332         </tr>
    333         <%
    334       }
    335       %>
    336329      <tr>
    337330        <td class="prompt">Protocol</td>
     
    378371 
    379372      <%
    380       if (extract.isPooled())
    381       {
    382         ItemQuery<Extract> extractsQuery = (ItemQuery<Extract>)creationEvent.getSources();
    383         extractsQuery.include(Include.ALL);
    384         extractsQuery.order(Orders.asc(Hql.property("name")));
    385         ItemResultList<Extract> extracts = extractsQuery.list(dc);
    386         %>
    387         <h4 class="docked">Pooled from extracts</h4>
    388         <tbl:table
    389           id="pooled"
    390           clazz="itemlist"
    391           columns="all"
     373      SpecialQuery<BioMaterialEventSource> sourceQuery = creationEvent.getEventSources();
     374      sourceQuery.order(Orders.asc(Hql.property("bioMaterial.name")));
     375      ResultList<BioMaterialEventSource> sources = sourceQuery.list(dc);
     376      if (sources.size() == 0)
     377      {
     378        %>
     379        <h4>Parent items</h4>
     380        This extract doesn't have any parent items
     381        (or, you don't have permission to view them).
     382        <%
     383      }
     384      else
     385      {
     386        %>
     387        <base:section
     388          id="parentsSection"
     389          title="<%="Parent items (" + sources.size() + ")"%>"
     390          context="<%=cc%>"
    392391          >
    393         <tbl:columndef
    394           id="name"
    395           title="Name"
    396         />
    397         <tbl:columndef
    398           id="quantity"
    399           title="Used quantity (µg)"
    400         />
    401         <tbl:columndef
    402           id="description"
    403           title="Description"
    404         />
    405         <tbl:data>
    406           <tbl:columns>
    407           </tbl:columns>
    408           <tbl:rows>
    409           <%
    410           for (Extract item : extracts)
    411           {
    412             %>
    413             <tbl:row>
    414               <tbl:cell column="name"><base:icon
     392          <tbl:table
     393            id="parents"
     394            clazz="itemlist"
     395            columns="all"
     396            >
     397          <tbl:columndef
     398            id="name"
     399            title="Name"
     400          />
     401          <tbl:columndef
     402            id="type"
     403            title="Type"
     404          />
     405          <tbl:columndef
     406            id="quantity"
     407            title="Used quantity (µg)"
     408          />
     409          <tbl:columndef
     410            id="description"
     411            title="Description"
     412          />
     413          <tbl:data>
     414            <tbl:columns>
     415            </tbl:columns>
     416            <tbl:rows>
     417            <%
     418            for (BioMaterialEventSource item : sources)
     419            {
     420              BioMaterial bm = null;
     421              try
     422              {
     423                bm = item.getBioMaterial();
     424              }
     425              catch (PermissionDeniedException ex)
     426              {}
     427              %>
     428              <tbl:row>
     429                <tbl:cell column="name"><base:icon
    415430                  image="deleted.gif"
    416431                  tooltip="This item has been scheduled for deletion"
    417                   visible="<%=item.isRemoved()%>"
    418                 /><%=Base.getLinkedName(ID, item, false, true)%></tbl:cell>
    419               <tbl:cell column="quantity"><%=Values.formatNumber(creationEvent.getUsedQuantity(item), 2)%></tbl:cell>
    420               <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
    421             </tbl:row>
    422             <%
    423           }
    424           %>
     432                  visible="<%=bm != null && bm.isRemoved()%>"
     433                  /><%=Base.getLinkedName(ID, bm, bm == null, true)%></tbl:cell>
     434                <tbl:cell column="type"><%=bm != null ? bm.getType() : "" %></tbl:cell>
     435                <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
     436                <tbl:cell column="description"><%=HTML.encodeTags(bm == null ? "" : bm.getDescription())%></tbl:cell>
     437              </tbl:row>
     438              <%
     439            }
     440            %>
    425441          </tbl:rows>
    426         </tbl:data>
    427         </tbl:table>
    428         <%
    429       }
    430 
    431       // Extracts this item is pooled in.
    432       ItemQuery<BioMaterialEvent> poolingQuery = extract.getPoolingEvents();
    433       ItemResultList<BioMaterialEvent> poolingEvents = poolingQuery.list(dc);
    434       if (poolingEvents.size() == 0)
    435       {
    436         %>
    437         <h4>Pooled in extracts</h4>
    438         No extracts have been pooled from this extract
     442          </tbl:data>
     443          </tbl:table>
     444        </base:section>
     445        <%
     446      }
     447     
     448      SpecialQuery<BioMaterialEventSource> childQuery = extract.getChildCreationEvents();
     449      childQuery.join(Hql.innerJoin("es", "event", "evt", true));
     450      childQuery.join(Hql.leftJoin("evt", "bioMaterial", "bm", null, true));
     451      childQuery.join(Hql.leftJoin("evt", "physicalBioAssay", "pba", null, true));
     452      childQuery.order(Orders.asc(Hql.property("pba", "name")));
     453      childQuery.order(Orders.asc(Hql.property("bm", "name")));
     454      ResultList<BioMaterialEventSource> children = childQuery.list(dc);
     455      if (children.size() == 0)
     456      {
     457        %>
     458        <h4>Child items</h4>
     459        No child items have been created from this extract
    439460        (or, you don't have permission to view them).
    440461        <%
     
    444465        %>
    445466        <base:section
    446           id="pooledSection"
    447           title="<%="Pooled in extracts (" + poolingEvents.size() + ")"%>"
     467          id="childSection"
     468          title="<%="Child items (" + children.size() + ")"%>"
    448469          context="<%=cc%>"
    449470          >
    450471          <tbl:table
    451             id="poolChilds"
     472            id="children"
    452473            clazz="itemlist"
    453474            columns="all"
     
    458479            />
    459480            <tbl:columndef
    460               id="quantity"
    461               title="Original quantity (µg)"
     481              id="type"
     482              title="Type"
    462483            />
    463484            <tbl:columndef
    464               id="parents"
    465               title="Used extracts[quantity]"
     485              id="quantity"
     486              title="Used quantity (µg)"
    466487            />
    467488            <tbl:columndef
     
    473494              <tbl:rows>
    474495              <%
    475               for (BioMaterialEvent poolEvt : poolingEvents)
     496              for (BioMaterialEventSource item : children)
    476497              {
    477                 ItemQuery<Extract> extractsQuery = (ItemQuery<Extract>)poolEvt.getSources();
    478                 Extract child = (Extract)poolEvt.getBioMaterial();
    479                 extractsQuery.include(Include.ALL);
    480                 extractsQuery.order(Orders.asc(Hql.property("name")));
    481                 ItemResultList<Extract> parentExtracts = extractsQuery.list(dc);
     498                CommonItem child = null;
     499                try
     500                {
     501                  BioMaterialEvent evt = item.getEvent();
     502                  if (evt.getEventType() == BioMaterialEvent.Type.BIOASSAY)
     503                  {
     504                    child = evt.getPhysicalBioAssay();
     505                  }
     506                  else
     507                  {
     508                    child = evt.getBioMaterial();
     509                  }
     510                }
     511                catch (PermissionDeniedException ex)
     512                {}
    482513                %>
    483514                <tbl:row>
    484                   <tbl:cell column="name">
    485                     <base:icon
     515                  <tbl:cell column="name"><base:icon
    486516                      image="deleted.gif"
    487517                      tooltip="This item has been scheduled for deletion"
    488                       visible="<%=child.isRemoved()%>"
    489                     />
    490                     <%=Base.getLinkedName(ID, child, false, true)%>
    491                   </tbl:cell>
    492                   <tbl:cell column="quantity"><%=Values.formatNumber(child.getOriginalQuantity(), 2)%></tbl:cell>
    493                   <tbl:cell column="parents">
    494                   <%
    495                   String separator = "";
    496                   for (Extract parent : parentExtracts)
    497                   {
    498                     out.write(separator);
    499                     if (parent.equals(extract))
    500                         out.write(HTML.encodeTags(parent.getName()));
    501                     else                   
    502                       out.write(Base.getLinkedName(ID, parent, false, true));
    503                     out.write("[" + Values.formatNumber(poolEvt.getUsedQuantity(parent), 2) + "µg]");
    504                     separator = ", ";
    505                   }
    506                   %>
    507                   </tbl:cell>
    508                   <tbl:cell column="description"><%=HTML.encodeTags(child.getDescription())%></tbl:cell>
     518                      visible="<%=child != null && child.isRemoved()%>"
     519                    /><%=Base.getLinkedName(ID, child, child == null, true)%></tbl:cell>
     520                  <tbl:cell column="type"><%=child != null ? child.getType() : "" %></tbl:cell>
     521                  <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
     522                  <tbl:cell column="description"><%=HTML.encodeTags(child == null ? "" : child.getDescription())%></tbl:cell>
    509523                </tbl:row>
    510524                <%
     
    517531        <%
    518532      }
    519      
    520       ItemQuery<PhysicalBioAssay> bioAssayQuery = extract.getPhysicalBioAssays();
    521       bioAssayQuery.include(Include.ALL);
    522       bioAssayQuery.order(Orders.asc(Hql.property("name")));
    523       ItemResultList<PhysicalBioAssay> bioAssays = bioAssayQuery.list(dc);
    524       if (bioAssays.size() == 0)
    525       {
    526         %>
    527         <h4>Physical bioassays</h4>
    528         No bioassays have been created from this extract
    529         (or you don't have the permission to view them)
    530         <%
    531       }
    532       else
    533       {
    534         %>
    535         <base:section
    536           id="bioAssaysSection"
    537           title="<%="Physical bioassays (" + bioAssays.size() + ")"%>"
    538           context="<%=cc%>"
    539           >
    540           <tbl:table
    541             id="bioAssays"
    542             clazz="itemlist"
    543             columns="all"
    544             >
    545             <tbl:columndef
    546               id="name"
    547               title="Name"
    548             />         
    549             <tbl:columndef
    550               id="quantity"
    551               title="Used quantity (µg)"
    552             />
    553             <tbl:columndef
    554               id="description"
    555               title="Description"
    556             />
    557             <tbl:data>
    558               <tbl:columns></tbl:columns>
    559               <tbl:rows>
    560                 <%
    561                 for (PhysicalBioAssay pba : bioAssays)
    562                 {
    563                   %>
    564                   <tbl:row>
    565                     <tbl:cell column="name"><base:icon
    566                       image="deleted.gif"
    567                       tooltip="This item has been scheduled for deletion"
    568                       visible="<%=pba.isRemoved()%>"
    569                     /><%=Base.getLinkedName(ID, pba, false, true)%></tbl:cell>
    570                     <tbl:cell column="quantity"><%=Values.formatNumber(pba.getCreationEvent().getUsedQuantity(extract), 2)%></tbl:cell>
    571                     <tbl:cell column="description"><%=HTML.encodeTags(pba.getDescription())%></tbl:cell>
    572                   </tbl:row>
    573                   <%
    574                 }
    575                 %>
    576               </tbl:rows>
    577             </tbl:data>
    578           </tbl:table>
    579         </base:section>
    580         <%
    581       }     
    582533      %>
    583534      <jsp:include page="../../common/anytoany/list_anytoany.jsp">
  • trunk/www/biomaterials/samples/edit_sample.jsp

    r5663 r5664  
    469469    {
    470470      var frm = document.forms['sample'];
    471       var useSamples = frm.parentType[1].checked
     471      var useSamples = frm.parentType[1].checked;
    472472      frm.biosource_id.disabled = useSamples;
    473473      frm.samples.disabled = !useSamples;
     
    815815          <td>
    816816            <table border="0" cellspacing="0" cellpadding="0">
    817             <tr><td style="padding: 1px 0px 4px 0px; width: 150px;"><base:button
     817            <tr><td style="padding: 1px 0px 4px 0px;"><base:button
     818              style="width: 150px;"
    818819              onclick="addSamplesOnClick()"
    819820              title="Add&nbsp;samples&hellip;"
  • trunk/www/biomaterials/samples/index.jsp

    r5663 r5664  
    6161  import="net.sf.basedb.util.formatter.WellCoordinateFormatter"
    6262  import="net.sf.basedb.util.formatter.NameableFormatter"
     63  import="net.sf.basedb.util.formatter.ItemTypeFormatter"
    6364  import="net.sf.basedb.clients.web.formatter.FormatterFactory"
    6465
     
    9192    cc.setObject("export.formatter.&childCreationEvents(event.bioMaterial.name)", new NameableFormatter());
    9293    cc.setObject("export.formatter.&children(name)", new NameableFormatter());
     94    cc.setObject("export.formatter.parentType", new ItemTypeFormatter());
    9395   
    9496    // Register dataloaders
     
    118120    parentSamplesQuery.order(Orders.asc(Hql.property("name")));
    119121    parentSamplesQuery.include(cc.getInclude());
    120     cc.setObject("export.dataloader.&creationEvent.sources(bioMaterial.name)", new ItemQueryLoader(parentSamplesQuery, sampleParameter));
     122    cc.setObject("export.dataloader.&creationEvent.sources(bioMaterial.name)", new ParentBioMaterialLoader(parentSamplesQuery, sampleParameter));
    121123  }
    122124%>
     
    264266 
    265267      // Parents tab
    266       //sample.setPooled(Values.getBoolean(request.getParameter("pooled")));
    267268      Item parentType = Item.valueOf(request.getParameter("parentType"));
    268269      if (parentType == Item.BIOSOURCE)
  • trunk/www/biomaterials/samples/list_samples.jsp

    r5663 r5664  
    101101  final ItemQuery<AnnotationType> annotationTypeQuery = Base.getAnnotationTypesQuery(itemType);
    102102  final ItemQuery<ItemSubtype> subtypesQuery = Base.getSubtypesQuery(itemType);
     103 
     104  // Child extracts
    103105  final ItemQuery<Extract> extractQuery = Extract.getQuery();
    104106  extractQuery.include(cc.getInclude());
     
    107109  final boolean createExtractPermission = sc.hasPermission(Permission.CREATE, Item.EXTRACT);
    108110
     111  // Child samples
    109112  final ItemQuery<Sample> childSamplesQuery = Sample.getQuery();
    110113  childSamplesQuery.join(Hql.innerJoin("creationEvent", "ce"));
     
    114117  childSamplesQuery.include(cc.getInclude());
    115118 
     119  // Parent samples
    116120  final ItemQuery<Sample> parentSamplesQuery = Sample.getQuery();
    117121  parentSamplesQuery.join(Hql.innerJoin("childCreationEvents", "cce"));
     
    377381        exportable="true"
    378382        formatter="<%=dateFormatter%>"
     383      />
     384      <%
     385      Enumeration<String, String> parentTypes = new Enumeration<String, String>();
     386      parentTypes.add(Integer.toString(Item.BIOSOURCE.getValue()), Item.BIOSOURCE.toString());
     387      parentTypes.add(Integer.toString(Item.SAMPLE.getValue()), Item.SAMPLE.toString());
     388      %>
     389      <tbl:columndef
     390        id="parentType"
     391        title="Parent type"
     392        property="parentType"
     393        enumeration="<%=parentTypes%>"
     394        datatype="int"
     395        filterable="true"
     396        exportable="true"
     397        sortable="true"
    379398      />
    380399      <tbl:columndef
     
    756775                <tbl:cell column="eventDate" value="<%=creationEvent.getEventDate()%>" />
    757776                <tbl:cell column="entryDate" value="<%=creationEvent.getEntryDate()%>" />
     777                <tbl:cell column="parentType"><%=parentType == null ? "" : parentType.toString() %></tbl:cell>
    758778                <tbl:cell column="parents">
    759779                  <%
    760                   if (item.hasSingleParent() || item.getParentType() == null)
     780                  if (item.hasSingleParent() || parentType == null)
    761781                  {
    762782                    %>
     
    783803                  }
    784804                  %>
     805                  <%=parentType != null ? "<span class=\"itemtype\">(" + parentType + ")</span>" : "" %>
    785806                </tbl:cell>
    786807                <tbl:cell column="children">
  • trunk/www/biomaterials/samples/view_sample.jsp

    r5663 r5664  
    373373      {
    374374        %>
     375        <h4>Parent items</h4>
     376        This sample doesn't have any parent items
     377        (or, you don't have permission to view them).
    375378        <%
    376379      }
     
    439442      }
    440443     
    441       // Samples this item is pooled in.
    442444      SpecialQuery<BioMaterialEventSource> childQuery = sample.getChildCreationEvents();
    443445      childQuery.join(Hql.innerJoin("es", "event", "evt", true));
  • trunk/www/include/styles/table.css

    r5426 r5664  
    199199}
    200200
    201 
     201.itemlist .itemtype {
     202  font-size: 10px;
     203  color: #777777;
     204}
     205
  • trunk/www/views/physicalbioassays/view_bioassay.jsp

    r5662 r5664  
    3535  import="net.sf.basedb.core.PhysicalBioAssay"
    3636  import="net.sf.basedb.core.ArraySlide"
     37  import="net.sf.basedb.core.BioMaterial"
    3738  import="net.sf.basedb.core.BioMaterialEvent"
    3839  import="net.sf.basedb.core.BioMaterialEventSource"
     
    4647  import="net.sf.basedb.core.MultiPermissions"
    4748  import="net.sf.basedb.core.ItemQuery"
     49  import="net.sf.basedb.core.SpecialQuery"
    4850  import="net.sf.basedb.core.Include"
    49   import="net.sf.basedb.core.ItemResultList"
    5051  import="net.sf.basedb.core.ItemResultList"
    5152  import="net.sf.basedb.core.PermissionDeniedException"
     
    5657  import="net.sf.basedb.core.query.Orders"
    5758  import="net.sf.basedb.core.query.Hql"
     59  import="net.sf.basedb.core.query.ResultList"
    5860  import="net.sf.basedb.clients.web.Base"
    5961  import="net.sf.basedb.clients.web.ChangeHistoryUtil"
     
    326328     
    327329      <%
    328       ItemQuery<Extract> extractsQuery = (ItemQuery<Extract>)creationEvent.getSources();
    329       extractsQuery.include(Include.ALL);
    330       extractsQuery.order(Orders.asc(Hql.property("srcevt", "position")));
    331       extractsQuery.order(Orders.asc(Hql.property("name")));
    332       ItemResultList<Extract> extracts = extractsQuery.list(dc);
    333       if (extracts.size() == 0)
     330      SpecialQuery<BioMaterialEventSource> sourceQuery = creationEvent.getEventSources();
     331      sourceQuery.order(Orders.asc(Hql.property("position")));
     332      sourceQuery.order(Orders.asc(Hql.property("bioMaterial.name")));
     333      ResultList<BioMaterialEventSource> sources = sourceQuery.list(dc);
     334      if (sources.size() == 0)
    334335      {
    335336        %>
     
    344345        <base:section
    345346          id="extractSection"
    346           title="<%="Extracts (" + extracts.size() + ")"%>"
     347          title="<%="Extracts (" + sources.size() + ")"%>"
    347348          context="<%=cc%>"
    348349          >
     
    378379            <tbl:rows>
    379380            <%
    380             for (Extract item : extracts)
     381            for (BioMaterialEventSource item : sources)
    381382            {
    382               BioMaterialEventSource evtSrc = creationEvent.getEventSource(item);
     383              BioMaterial bm = null;
     384              try
     385              {
     386                bm = item.getBioMaterial();
     387              }
     388              catch (PermissionDeniedException ex)
     389              {}
    383390              %>
    384391              <tbl:row>
    385                 <tbl:cell column="position"><%=evtSrc.getPosition()%></tbl:cell>
     392                <tbl:cell column="position"><%=item.getPosition()%></tbl:cell>
    386393                <tbl:cell column="name"><base:icon
    387394                    image="deleted.gif"
    388395                    tooltip="This item has been scheduled for deletion"
    389                     visible="<%=item.isRemoved()%>"
    390                   /><%=Base.getLinkedName(ID, item, false, true)%></tbl:cell>
    391                 <tbl:cell column="tag"><base:propertyvalue item="<%=item%>" property="tag" /></tbl:cell>
    392                 <tbl:cell column="quantity"><%=Values.formatNumber(evtSrc.getUsedQuantity(), 2)%></tbl:cell>
    393                 <tbl:cell column="description"><%=HTML.encodeTags(item.getDescription())%></tbl:cell>
     396                    visible="<%=bm != null && bm.isRemoved()%>"
     397                  /><%=Base.getLinkedName(ID, bm, bm == null, true)%></tbl:cell>
     398                <tbl:cell column="tag" visible="<%=bm != null && bm.getType() == Item.EXTRACT%>"><base:propertyvalue item="<%=bm%>" property="tag" /></tbl:cell>
     399                <tbl:cell column="quantity"><%=Values.formatNumber(item.getUsedQuantity(), 2)%></tbl:cell>
     400                <tbl:cell column="description"><%=HTML.encodeTags(bm == null ? "" : bm.getDescription())%></tbl:cell>
    394401              </tbl:row>
    395402              <%
Note: See TracChangeset for help on using the changeset viewer.