Bug 21666: Replace unsupported use attribute with more widely supported attribute
[koha.git] / koha-tmpl / intranet-tmpl / lib / koha / cateditor / koha-backend.js
1 /**
2  * Copyright 2015 ByWater Solutions
3  *
4  * This file is part of Koha.
5  *
6  * Koha is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Koha is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Koha; if not, see <http://www.gnu.org/licenses>.
18  */
19
20 define( [ '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=&callback=define', 'marc-record' ], function( defaultFramework, MARC ) {
21     var _authorised_values = defaultFramework.authorised_values;
22     var _frameworks = {};
23     var _framework_mappings = {};
24     var _framework_kohafields = {};
25
26     function _fromXMLStruct( data ) {
27         result = {};
28
29         $(data).children().eq(0).children().each( function() {
30             var $contents = $(this).contents();
31             if ( $contents.length == 1 && $contents[0].nodeType == Node.TEXT_NODE ) {
32                 result[ this.localName ] = $contents[0].data;
33             } else {
34                 result[ this.localName ] = $contents.filter( function() { return this.nodeType != Node.TEXT_NODE || !this.data.match( /^\s+$/ ) } ).toArray();
35             }
36         } );
37
38         return result;
39     }
40
41     function _importFramework( frameworkcode, frameworkinfo ) {
42         _frameworks[frameworkcode] = frameworkinfo;
43         _framework_mappings[frameworkcode] = {};
44
45         $.each( frameworkinfo, function( i, tag ) {
46             var tagnum = tag[0], taginfo = tag[1];
47
48             var subfields = {};
49
50             $.each( taginfo.subfields, function( i, subfield ) {
51                 subfields[ subfield[0] ] = subfield[1];
52                 if ( frameworkcode == '' && subfield[1].kohafield ) {
53                     _framework_kohafields[ subfield[1].kohafield ] = [ tagnum, subfield[0] ];
54                 }
55             } );
56
57             _framework_mappings[frameworkcode][tagnum] = $.extend( {}, taginfo, { subfields: subfields } );
58         } );
59     }
60
61     _importFramework( '', defaultFramework.framework );
62
63     function _removeBiblionumberFields( record ) {
64         var bibnumTag = KohaBackend.GetSubfieldForKohaField('biblio.biblionumber')[0];
65
66         while ( record.removeField(bibnumTag) );
67     }
68
69     function initFramework( frameworkcode, callback ) {
70         if ( typeof _frameworks[frameworkcode] === 'undefined' ) {
71             $.get(
72                 '/cgi-bin/koha/svc/cataloguing/framework?frameworkcode=' + frameworkcode
73             ).done( function( framework ) {
74                 _importFramework( frameworkcode, framework.framework );
75                 callback();
76             } ).fail( function( data ) {
77                 callback( 'Could not fetch framework settings' );
78             } );
79         } else {
80             callback();
81         }
82     }
83
84     var KohaBackend = {
85         NOT_EMPTY: {}, // Sentinel value
86
87         InitFramework: initFramework,
88
89         GetAllTagsInfo: function( frameworkcode, tagnumber ) {
90             return _framework_mappings[frameworkcode];
91         },
92
93         GetAuthorisedValues: function( category ) {
94             return _authorised_values[category];
95         },
96
97         GetTagInfo: function( frameworkcode, tagnumber ) {
98             if ( !_framework_mappings[frameworkcode] ) return undefined;
99             return _framework_mappings[frameworkcode][tagnumber];
100         },
101
102         GetSubfieldForKohaField: function( kohafield ) {
103             return _framework_kohafields[kohafield];
104         },
105
106         GetRecord: function( id, callback ) {
107             $.get(
108                 '/cgi-bin/koha/svc/bib/' + id
109             ).done( function( metadata ) {
110                 $.get(
111                     '/cgi-bin/koha/svc/bib_framework/' + id
112                 ).done( function( frameworkcode ) {
113                     var record = new MARC.Record();
114                     record.loadMARCXML(metadata);
115                     record.frameworkcode = $(frameworkcode).find('frameworkcode').text();
116                     initFramework( record.frameworkcode, function( error ) {
117                         if ( typeof error === 'undefined' ) {
118                             callback( record );
119                         } else {
120                             callback( { error: error } );
121                         }
122                     });
123                 } ).fail( function( data ) {
124                     callback( { error: _('Could not fetch frameworkcode for record') } );
125                 } );
126             } );
127         },
128
129         CreateRecord: function( record, callback ) {
130             var frameworkcode = record.frameworkcode;
131             record = record.clone();
132             _removeBiblionumberFields( record );
133
134             $.ajax( {
135                 type: 'POST',
136                 url: '/cgi-bin/koha/svc/new_bib?frameworkcode=' + encodeURIComponent(frameworkcode),
137                 data: record.toXML(),
138                 contentType: 'text/xml'
139             } ).done( function( data ) {
140                 var record = _fromXMLStruct( data );
141                 if ( record.marcxml ) {
142                     record.marcxml[0].frameworkcode = frameworkcode;
143                 }
144                 callback( record );
145             } ).fail( function( data ) {
146                 callback( { error: _('Could not save record') } );
147             } );
148         },
149
150         SaveRecord: function( id, record, callback ) {
151             var frameworkcode = record.frameworkcode;
152             record = record.clone();
153             _removeBiblionumberFields( record );
154
155             $.ajax( {
156                 type: 'POST',
157                 url: '/cgi-bin/koha/svc/bib/' + id + '?frameworkcode=' + encodeURIComponent(frameworkcode),
158                 data: record.toXML(),
159                 contentType: 'text/xml'
160             } ).done( function( data ) {
161                 var record = _fromXMLStruct( data );
162                 if ( record.marcxml ) {
163                     record.marcxml[0].frameworkcode = frameworkcode;
164                 }
165                 callback( record );
166             } ).fail( function( data ) {
167                 callback( { error: _('Could not save record') } );
168             } );
169         },
170
171         GetTagsBy: function( frameworkcode, field, value ) {
172             var result = {};
173
174             $.each( _frameworks[frameworkcode], function( undef, tag ) {
175                 var tagnum = tag[0], taginfo = tag[1];
176
177                 if ( taginfo[field] == value && taginfo.tab != '-1' ) result[tagnum] = true;
178             } );
179
180             return result;
181         },
182
183         GetSubfieldsBy: function( frameworkcode, field, value ) {
184             var result = {};
185
186             $.each( _frameworks[frameworkcode], function( undef, tag ) {
187                 var tagnum = tag[0], taginfo = tag[1];
188
189                 $.each( taginfo.subfields, function( undef, subfield ) {
190                     var subfieldcode = subfield[0], subfieldinfo = subfield[1];
191
192                     if ( subfieldinfo[field] == value ) {
193                         if ( !result[tagnum] ) result[tagnum] = {};
194
195                         result[tagnum][subfieldcode] = true;
196                     }
197                 } );
198             } );
199
200             return result;
201         },
202
203         FillRecord: function( frameworkcode, record, allTags ) {
204             $.each( _frameworks[frameworkcode], function( undef, tag ) {
205                 var tagnum = tag[0], taginfo = tag[1];
206
207                 if ( taginfo.mandatory != "1" && !allTags ) return;
208
209                 var fields = record.fields(tagnum);
210
211                 if ( fields.length == 0 ) {
212                     var newField = new MARC.Field( tagnum, ' ', ' ', [] );
213                     fields.push( newField );
214                     record.addFieldGrouped( newField );
215
216                     if ( tagnum < '010' ) {
217                         newField.addSubfield( [ '@', (taginfo.subfields[0] ? taginfo.subfields[0][1].defaultvalue : null ) || '' ] );
218                         return;
219                     }
220                 }
221
222                 $.each( taginfo.subfields, function( undef, subfield ) {
223                     var subfieldcode = subfield[0], subfieldinfo = subfield[1];
224
225                     if ( subfieldinfo.mandatory != "1" && !subfieldinfo.defaultvalue && !allTags ) return;
226
227                     $.each( fields, function( undef, field ) {
228                         if ( !field.hasSubfield(subfieldcode) ) {
229                             field.addSubfieldGrouped( [ subfieldcode, subfieldinfo.defaultvalue || '' ] );
230                         } else if ( subfieldinfo.defaultvalue && field.subfield( subfieldcode ) === '' ) {
231                             field.subfield( subfieldcode, subfieldinfo.defaultvalue );
232                         }
233                     } );
234                 } );
235             } );
236         },
237
238         ValidateRecord: function( frameworkcode, record ) {
239             var errors = [];
240
241             var mandatoryTags = KohaBackend.GetTagsBy( record.frameworkcode, 'mandatory', '1' );
242             var mandatorySubfields = KohaBackend.GetSubfieldsBy( record.frameworkcode, 'mandatory', '1' );
243             var nonRepeatableTags = KohaBackend.GetTagsBy( record.frameworkcode, 'repeatable', '0' );
244             var nonRepeatableSubfields = KohaBackend.GetSubfieldsBy( record.frameworkcode, 'repeatable', '0' );
245
246             $.each( mandatoryTags, function( tag ) {
247                 if ( !record.hasField( tag ) ) errors.push( { type: 'missingTag', tag: tag } );
248             } );
249
250             var seenTags = {};
251             var itemTag = KohaBackend.GetSubfieldForKohaField('items.itemnumber')[0];
252
253             $.each( record.fields(), function( undef, field ) {
254                 if ( field.tagnumber() == itemTag ) {
255                     errors.push( { type: 'itemTagUnsupported', line: field.sourceLine } );
256                     return;
257                 }
258
259                 if ( seenTags[ field.tagnumber() ] && nonRepeatableTags[ field.tagnumber() ] ) {
260                     errors.push( { type: 'unrepeatableTag', line: field.sourceLine, tag: field.tagnumber() } );
261                     return;
262                 }
263
264                 seenTags[ field.tagnumber() ] = true;
265
266                 var seenSubfields = {};
267
268                 $.each( field.subfields(), function( undef, subfield ) {
269                     if ( seenSubfields[ subfield[0] ] != null && ( nonRepeatableSubfields[ field.tagnumber() ] || {} )[ subfield[0] ] ) {
270                         errors.push( { type: 'unrepeatableSubfield', subfield: subfield[0], line: field.sourceLine } );
271                     } else {
272                         seenSubfields[ subfield[0] ] = subfield[1];
273                     }
274                 } );
275
276                 $.each( mandatorySubfields[ field.tagnumber() ] || {}, function( subfield ) {
277                     if ( !seenSubfields[ subfield ] ) {
278                         errors.push( { type: 'missingSubfield', subfield: subfield[0], line: field.sourceLine } );
279                     }
280                 } );
281             } );
282
283             return errors;
284         },
285     };
286
287     return KohaBackend;
288 } );