specify / specify7

Specify 7
https://www.specifysoftware.org/products/specify-7/
GNU General Public License v2.0
61 stars 36 forks source link

Configured catalogNumber format not being respected #5056

Open lexiclevenger opened 2 months ago

lexiclevenger commented 2 months ago

Describe the bug On this database, the configured catalogNumber format 'CatalogNumberHerpetos' is displayed in the catalogNumber field. However, when a CO record is saved with that field format, an error is thrown because it does not match the format 'CatalogNumber.' The 'CatalogNumberHerpetos' format is saved in both the schema and in the Collection table, so the other format should not be used. The only solution for this is to comment out the 'CatalogNumber' format in the UI Formatters xml.

To Reproduce Steps to reproduce the behavior:

  1. Create a new CO record
  2. Save the record

Expected behavior The "CatalogNumberHerpetos" format should be respected instead of "CatalogNumber."

Screenshots

https://github.com/specify/specify7/assets/164079735/3c5e27c1-9822-4d2b-8a9f-c35a830f527c

Crash Report

Specify 7 Crash Report - 2024-06-28T20_36_45.131Z.txt

Please, also fill out the following information manually:

UI Formatters file:

<?xml version="1.0" encoding="UTF-8"?>
<formats>
  <format system="true" name="AccessionNumber" class="edu.ku.brc.specify.datamodel.Accession" fieldname="accessionNumber" default="true">
    <autonumber>edu.ku.brc.specify.dbsupport.AccessionAutoNumberAlphaNum</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="alphanumeric" size="2" value="AA"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="true"/>
  </format>

  <format system="true" name="AccessionStringFormatter" class="edu.ku.brc.specify.datamodel.Accession" fieldname="accessionNumber" default="true">
    <field type="alphanumeric" size="10" value="AAAAAAAAAA"/>
  </format>

  <format system="true" name="DeaccessionNumber" class="edu.ku.brc.specify.datamodel.Deaccession" fieldname="deaccessionNumber" default="true">
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="alphanumeric" size="2" value="AA"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="false"/>
  </format>

  <format system="true" name="AccessionNumberByYear" class="edu.ku.brc.specify.datamodel.Accession" fieldname="accessionNumber" default="true">
    <autonumber>edu.ku.brc.af.core.db.AutoNumberGeneric</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="alphanumeric" size="2" value="AA"/>
    <field type="separator" size="1" value="-"/>
    <field type="alphanumeric" size="3" value="AAA"/>
  </format>
    <format system="false" name="CatalogNumberHerpetos" class="edu.ku.brc.specify.datamodel.CollectionObject" fieldname="catalogNumber" default="true">
    <autonumber>edu.ku.brc.specify.dbsupport.CollectionAutoNumberAlphaNum</autonumber>
    <field type="constant" value="EBD"/>
    <field type="separator" size="1" value=" "/>
    <field type="numeric" size="5" inc="true"/>
    <field type="constant" value="H"/>
  </format>
  <format system="false" name="CatalogNumber" class="edu.ku.brc.specify.datamodel.CollectionObject" fieldname="catalogNumber" default="false">
    <autonumber>edu.ku.brc.specify.dbsupport.CollectionAutoNumber</autonumber>
    <field type="year" size="4" value="YEAR"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="6" inc="true"/>
  </format>
  <format system="false" name="CatalogNumberAlphaNumByYear" class="edu.ku.brc.specify.datamodel.CollectionObject" fieldname="catalogNumber">
    <autonumber>edu.ku.brc.specify.dbsupport.CollectionAutoNumber</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="6" inc="true"/>
  </format>
  <format system="true" name="CatalogNumberNumeric" class="edu.ku.brc.specify.datamodel.CollectionObject" fieldname="catalogNumber" default="false">
    <autonumber>edu.ku.brc.specify.dbsupport.CollectionAutoNumber</autonumber>
    <external>edu.ku.brc.specify.ui.CatalogNumberUIFieldFormatter</external>
  </format>
  <format system="true" name="CatalogNumberString" class="edu.ku.brc.specify.datamodel.CollectionObject" fieldname="catalogNumber" default="false">
    <external>edu.ku.brc.specify.ui.CatalogNumberStringUIFieldFormatter</external>
  </format>
  <format system="true" name="SearchDate" class="java.util.Date" type="date" partialdate="Full">
    <field type="year" size="4" value="YYYY"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="2" value="MM"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="2" value="DD"/>
  </format>
  <format system="true" name="GiftNumber" class="edu.ku.brc.specify.datamodel.Gift" fieldname="giftNumber" default="true">
    <autonumber>edu.ku.brc.af.core.db.AutoNumberGeneric</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="true"/>
  </format>
  <format system="true" name="InfoRequestNumber" class="edu.ku.brc.specify.datamodel.InfoRequest" fieldname="infoReqNumber" default="true">
    <autonumber>edu.ku.brc.af.core.db.AutoNumberGeneric</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="true"/>
  </format>
  <format system="true" name="LoanNumber" class="edu.ku.brc.specify.datamodel.Loan" fieldname="loanNumber" default="true">
    <autonumber>edu.ku.brc.af.core.db.AutoNumberGeneric</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="true"/>
  </format>

  <format system="true" name="GiftNumber" class="edu.ku.brc.specify.datamodel.Gift" fieldname="giftNumber" default="true">
    <autonumber>edu.ku.brc.af.core.db.AutoNumberGeneric</autonumber>
    <field type="year" size="4" value="YEAR" byyear="true"/>
    <field type="separator" size="1" value="-"/>
    <field type="numeric" size="3" inc="true"/>
  </format>
  <format system="true" name="NumericBigDecimal" class="java.math.BigDecimal" type="numeric">
  </format>
  <format system="true" name="NumericByte" class="java.lang.Byte" type="numeric">
  </format>
  <format system="true" name="NumericDouble" class="java.lang.Double" type="numeric">
  </format>
  <format system="true" name="NumericFloat" class="java.lang.Float" type="numeric">
  </format>
  <format system="true" name="NumericInteger" class="java.lang.Integer" type="numeric">
  </format>
  <format system="true" name="NumericLong" class="java.lang.Long" type="numeric">
  </format>
  <format system="true" name="NumericShort" class="java.lang.Short" type="numeric">
  </format>

   <!-- ********** Dates ********** -->
  <format system="true" name="Date" class="java.util.Date" type="date" partialdate="Full"/>

  <format system="true" name="PartialDate" class="java.util.Date" type="date" partialdate="Full">
    <external>edu.ku.brc.specify.ui.PartialDateFormatter</external>
  </format>

  <format system="true" name="PartialDateMonth" class="java.util.Date" type="date" partialdate="Month">
    <external>edu.ku.brc.specify.ui.PartialDateFormatter</external>
  </format>
  <format system="true" name="PartialDateYear" class="java.util.Date" type="date" partialdate="Year">
    <external>edu.ku.brc.specify.ui.PartialDateFormatter</external>
  </format>
  <format system="true" name="SearchDate" class="java.util.Date" type="date" partialdate="Search">
  </format>
</formats>
emenslin commented 1 month ago

Can recreate in edge (7.9.6.2)

melton-jason commented 1 month ago

This is because the backend does not use the schema configuration for CollectionObject -> catalogNumber to format the field.

Instead, it uses the Collection -> catalogNumFormatName and then references that formatter in the UIFormatters file.

https://github.com/specify/specify7/blob/196fe71f3ba3276b6fb766b1ed3a338362b01408/specifyweb/specify/uiformatters.py#L306-L329

https://github.com/specify/specify7/blob/196fe71f3ba3276b6fb766b1ed3a338362b01408/specifyweb/specify/uiformatters.py#L331-L345

This is a convention that Specify 6 uses which Specify 7 has to maintain for compatibility. Thus the only way to actually change the format of CollectionObject -> catalogNumber in Specify 7, you have to:

There are instructions on how to accomplish this in Specify 6 (the instructions include modifying the Collection via SQL).

https://discourse.specifysoftware.org/t/to-change-a-catalog-number-format-other-than-default/283

The process/workflow leaves much to be desired however, and can be vastly improved. I think a much better solution (assuming we still need to maintain compatibility with Specify 6) would be to implicitly update the Collection -> catalogNumFormatName whenever a new format is set for CollectionObject -> catalogNumber in the Schema Configuration. Most users are probably expecting the process of changing CollectionObject -> catalogNumber format to be the same as any other field in Specify, but it is not.

lexiclevenger commented 1 month ago

@melton-jason The format name "CatalogNumberHerpetos" is already the value for catalogNumFormatName in the Collection table. Normally, I can successfully change the value by adding the catalogNumFormatName field to the Collection form and inputting the name of the desired field format. In this case, the format named "CatalogNumber" is still being enforced. Once the format "CatalogNumber" is removed, the format "CatalogNumberHerpetos" functions as it should.

grantfitzsimmons commented 1 month ago

I saw the same when I was working with @lexiclevenger and it left me perplexed