= Drawing Code Handling = <> 1. Drawing codes are composed of components, each of which (generally) has a meaning. 1. The drawing code components can be mapped to classification (and other fields) in the Drawings record. * Maps may be direct (to reference tables) or indirect, e.g. via drawing code map tables (see below). 1. There is a complex syntax described in SomePage (?) * Drawing codes structures are defined in '''app/config/Settings-DrawingCode.php''' * Drawing code functionality is implemented in '''app/lib/DrawingCodeBase.php''' == Drawing Code Definition == The drawing code definition is defined in: 1. The database table '''DrawingCodeTypeRef''', where an id, code and name for each drawing code type is defined. 1. The configuration file '''app/config/Settings-DrawingCode.php''', which defines all the components of each drawing code. == Drawing Code Component Definition == The drawing codes are defined in the '''$_CFG''' settings array. Each Drawing Code has two parts: 1. '''DrawingCode''' - defines each drawing code component and separator 2. '''RevisionCode''' - defines: * each revision code component * revision numbering rules (starting revision number, are gaps allowed) * file storage rules for the publish and source files (how the files are named internally) === Top-Level Configuration === {{{ $_CFG[ 'DrawingCodeDefinitions' ] = array( DrawingCodeTypeRef_DC1 => array( // KEJV: 14-C-9.99.999 'name' => 'KEJV', 'drawingCode' => array( // KEJV Drawing code definition 'components' => array( ... ) ), 'revisionCode' => array( // KEJV Revision code definition 'components' => array( ... ) ... ), ), DrawingCodeTypeRef_DC2 => array( // ... ... ), ), }}} === Component Definition === Components are defined as a series of arrays (starting with component zero): The following example shows a simple document code with three components: ||<-3> '''Drawing Code''' || || X || - || 9999 || '''Components''' || '''Component''' || '''Name''' || '''Description''' || || X || Category || Engineering discipline, a single character taken from the field CategoryRef.code || || - || Separator || Constant text || || 9999 || Sequence || Four-digit sequence number, with the ability to ask it from the system || This is the definition in '''app/config/Settings-DrawingCode.php''' {{{ 'drawingCode' => array( // Example drawing code definition 'components' => array( array( // Component 0: Category - Direct map 'name' => 'Category', 'tag' => 'catagory', 'type' => 'select', 'length' => 1, 'rmTable' => 'CategoryRef', 'rmCode' => 'code', 'rmName' => 'CODE_NAME', 'rmField' => 'categoryId', 'parse' => '/^[A-Z]{0,1}$/', 'pattern' => '/^[A-Z]{1,1}$/', 'fieldOut' => 'categoryId', ), array( // Component 1: Separator - Constant text 'type' => 'constant', 'value' => '-', 'parse' => '-', ), array( // Component 2: Sequence number - Manual entry field 'name' => 'Sequence Number', 'type' => 'manual', 'length' => 4, 'formatCode' => '%04d', 'fieldOut' => 'drawingNo', 'formatOut' => '%d', 'parse' => '/^\d{0,4}$/', 'pattern' => '/^\d{1,4}$/', 'getNext' => 'getNextDrawingNo', 'getNextPattern' => array(0,1), ), ), ), }}} Notes about the components: 1. The category is a select field of a single character, and maps directly to the field Drawings.categoryId. 1. The separator is constant text. 1. The sequence number is a manual entry value, which must be numeric. It maps directly to Drawings.drawingNo. 1. The next free sequence number can be asked from the system (see getNext and getNextPattern). == Drawing Code Syntax and Keywords == === Component Keywords === There are many component keywords. The complete list of valid keywords is defined below. || '''Keyword''' || '''Description''' || || counterIn || Name of counter field (See below) || || fieldIn || Name of field used for initializing the componenet value || || fieldOut || Name of field to which the component value should be copied || || formatCode || Printf style format code used for building the code || || formatIn || Scanf style format code for converting the component into a value for entry || || formatOut || Printf style format code used for converting the component into into the destination field || || frameIn || Name of session frame variable for retrieving the conponent value || || length || Component length in characters || || mapId || Id value for an indirect map. Maps to DrawingCodeMapRef.mapId (see below). || || name || Name of component, use for building a validation tag || || nullClip || Number of characters to remove from code if this component is empty. For removing separators || || parse || Length (if numeric), or constant text, or regular expression (if starting with slash character) used to parse/extract the component from user input || || pattern || Length (if numeric), or regular expression used to parse/extract the component from the code || || readonly || Set to true if the component cannot be modified || || replaceIn || Two component array of: 1) search regular rexpresssion, 2) text that it should be replaced with || || required || Set to false if component is options. Defaults to true if not present || || rmCode || Direct map: Field name (from target table) to use as value for component (typically code) || || rmField || Direct map: Target field name || || rmFilter || Direct map: Filter field name, Typically contractId || || rmFilterValue || Direct map: Filter constat value. || || rmName || Direct map: Name of field(s) to display in list. Typically, code, name or CODE_NAME. || || rmTable || Direct map: Target table name || || tag || Message tag used to display component name || || type || Component type. See below. || || value || Constant text for fields of ''constant'' type. || || getNext || Button appears beside this field on the form. Button tag and the name of the event generated by the button are the value of this option. Used to generate the next free DrawingNo, Part Number || || getNextPattern || An array containing the indexes of the drawing code components participating in search for the next free value. || === Component Types === || '''Type''' || '''Description''' || || constant || Component is constant text, typically used for separator characters. || || counter || Component is a numeric counter. See below. || || manual || Component is manual entry (e.g. no select list is available). Typically used for sequence numbers || || select || Component is a select list, requires that a mapping is defined. || == Revision Keywords == These keywords apply to RevisionCode definitions: || '''Keyword''' || '''Description''' || || firstRevisionNo || Initial revisionNo value. Typically 0 or 1. || || gapsAllowed || True is revisionNo gaps are allowed || || publishFilenameFields || Used together with publishFilenameFormat for building filename. See below. || || publishFilenameFile || How publish file is named internally on server. See below. || || publishFilenameFormat || Used together with publishFilenameFields for building filename. See below. || || publishFilenameName || How publish file is named when downloaded. See below. || || publishFilenameReplace || Regular expression transformation of filename. See below. || || revisionNumberComponent || The component number where the revisionNo appears. Required || || sourceFilenameFields || Used together with sourceFilenameFormat for building filename. See below. || || sourceFilenameFile || How source file is named internally on server. See below. || || sourceFilenameFormat || Used together with sourceFilenameFields for building filename. See below. || || sourceFilenameName || How publish file is named when downloaded. See below. || || sourceFilenameReplace || Regular expression transformation of filename. See below. || Note that there are many ways for creating filenames, including two methods of creating filenames that are derived from the drawing/revision codes: 1. FilenameReplace - For performing regular express transformation for filenames. 2. Filename File/Name - For ''build'' more complex filenames. Example of their usage are shown below. '''Filename File/Name Handling''' Filename handling refers to the technique (or strategy) for how file names are assigned to source and publish files. This applies to the following fields: * publishFilenameFile * publishFilenameName * sourceFilenameFile * sourceFilenameName. The filename handling determines how document files are named. * FilenameFile: Internal filename. Determines how the document files are named internally on the server * FilenameName: User filename. Determines how the file is named when the user downloads it. || '''Keyword''' || '''Value''' || || code || The file must be named exactly according to the document code || || format || The file name is determined by a regular expression transformation of the drawing code || || free || The file name unrestricted || || system || The file name is determined by the system, based in internal ids. See InternalFileNames. || ''' Fielname Replace''' FilenameReplace can be used for making relatively simple transformation from a drawing/revision code to a file name. Typically it us used to transform a drawing code's separator characters into alternate characters. A normal use is to durn periods (.) into underline characters (_). The syntax is an array of search replacement pairs: {{{ 'sourceFilenameReplace' = array( pattern-1, replace-1, pattern-2, replace-2, ... pattern-n, replace-n, ), }}} * ''pattern'' - regular expression * ''replace'' - replacemet text The pattern/replacements are applied sequentially in the order in which they were defined. The following example shows an example where a drawing code has dots replaced with underlines and the leading underline in front of a black revision is deleted: || '''Drawing Code''' || '''Filename''' || || CCC.9999.99.9999_A || CCC_9999_99_9999_A.pdf || || CCC.9999.99.9999_ || CCC_9999_99_9999.pdf || This is the definition: {{{ 'sourceFilenameReplace' => array( '/\./', '_', // 1. Replace dots with _ '/_$/', '' // 2. Delete trailing '_' for blank rev. ), }}} '''Filename Fields/Format''' For building more complex filenames, FilenameFields and FilenameFormat, can be used to construct a filename using a printf-style format string and an array of components. '''TODO: Complete this section.''' {{{ 'sourceFilenameFormat' => '%s_%s_%s', 'sourceFilenameFields' => array( // code_sheet_rev array( 'field' => 'drawingCode', 'table' => 'Drawings', 'replace' => array( '/\-{1,2}[0-9]$/', '' ), ), array( 'field' => 'sheetNo', 'table' => 'Drawings', 'default' => '1', ), array( 'field' => 'revisionCode', 'table' => 'Revisions', 'default' => '0', ), ), }}} Note that FilenameReplace and FilenameFields/FilenameFormat can both be used. ''TODO: Check the order in which replace and fields/format are applied'' === Counters === '''TODO: to be completed''' == Drawing Code Maps == Drawing code maps allow classification (and other) fields to be directly set based on drawing code components. This is main mechanism for automatically setting classification fields based on a drawing code. === There are two kinds of maps === 1. '''Direct maps''' - map a drawing code component value directly to the code of the target field 1. '''Indirect maps''' - which use DrawingCodeMap tables to map from a drawing code component value to one (or more) target field/values pairs. === Set the drawing code input fields based on a change in a classification field and v.v. === If the checkbox 'setClassifications' is checked on the new/update form, the drawing code input fields will be changed on a change in a classification field (see function '''setDCField()''' in '''drawmgt.js''') and v.v. (see function '''populateValueById()''' in '''drawmgt.js'''). The default value of 'setClassifications' is determined by $_CFG['SetClassifications']['Document'/'Revision']['New'/'Update']. All of these values are set to '''true''' in Settings.php. If you want, that drawing code fields and classification fields always correspond to each other, leave these configuration values '''true''' and set the checkbox 'setClassifications' to hidden (style="display:none") to disable overwriting of the default. ---- = Examples = == Example: Direct Mapping == Uses the '''rmTable, rmCode, rmName, rmField''' keywords. Suppose a drawing code component requires a mapping from a single character code directly to the CategoryRef.code classification The following definition is required: {{{ 'drawingCode' => array( // Example drawing code definition 'components' => array( ... array( // Component with direct map 'name' => 'Category', 'type' => 'select', 'length' => 1, 'rmTable' => 'CategoryRef', 'rmCode' => 'code', 'rmName' => 'CODE_NAME', 'rmField' => 'categoryId', 'parse' => '/^[A-Za-z]{0,1}$/', 'pattern' => '/^[A-Z]{1,1}$/', 'fieldOut' => 'categoryId', ), ... }}} == Example: Indirect Mapping == Uses the '''mapId''' keyword. Suppose a drawing code component requires the following indirect mapping: || '''Drawing Code''' ||<-2> '''Mapping''' || Description || || '''Component''' || '''projectPhaseId''' || '''categoryId''' || || || A || 101 (1 - Design) || 205 (E - Electrical) || Double mapping || || B || 102 (2 - Construction) || || Single mapping || || C || || 203 (C - Civil) || Single mapping || || D || 103 (3 - Planning) || 205 (E - Electrical) || Double mapping || || E || || || No mapping || The indirect mapping uses the following database tables: * '''DrawingCodeMapRef''' - Defines a drawing code component map (basically its name and id) * '''DrawingCodeMapCodes''' - Defines the code values allowed for the drawing code component * '''DrawingCodeMapValues''' - Defines mapping from the drawing code component values to classification id values Define the map, which we arbitrarily call EX1, in the '''DrawingCodeMapRef''' table: ||<-5> '''DrawingCodeMapRef''' || || drawingCodeMapId || code || name || description || define || || 1001 || EX1 || Example Map || null || EX1 || Define the possible component codes, which appear in the component's select list, in the '''DrawingCodeMapCodes''' table: ||<-5> '''DrawingCodeMapCodes''' || || drawingCodeMapId || code || contractId || name || description || || 1001 || A || 0 || Design/E || null || || 1001 || B || 0 || Construction || null || || 1001 || C || 0 || Civil || null || || 1001 || D || 0 || Planning/E || null || || 1001 || E || 0 || Concept || null || Define the mappings of the codes to the target fields in the '''DrawingCodeMapValues''' table: ||<-6> '''DrawingCodeMapValues''' || || drawingCodeMapId || code || contractId || fieldName || valueId || valueChar || || 1001 || A || 0 || projectPhaseId || 101 || null || || 1001 || A || 0 || categoryId || 205 || null || || 1001 || B || 0 || projectPhaseId || 102 || null || || 1001 || C || 0 || categoryId || 203 || null || || 1001 || D || 0 || projectPhaseId || 103 || null || || 1001 || D || 0 || categoryId || 205 || null || Note that no record for code '''E''' is required in the DrawingCodeMapValues table. The following component definition is required: {{{ 'drawingCode' => array( // Example drawing code definition 'components' => array( ... array( // Component with indirect map 'name' => 'EX1', 'type' => 'select', 'length' => 1, 'mapId' => 1001, 'parse' => 1, 'pattern' => '/^[A-Z]{1,1}$/', ), ... }}}