99
1010const config = require ( 'config' ) ;
1111const { sql } = require ( 'slonik' ) ;
12- const { map, compose } = require ( 'ramda' ) ;
12+ const { map } = require ( 'ramda' ) ;
1313const { Frame, into } = require ( '../frame' ) ;
1414const { Actor, Blob, Form, Dataset } = require ( '../frames' ) ;
1515const { getFormFields, merge, compare } = require ( '../../data/schema' ) ;
@@ -18,7 +18,7 @@ const { generateToken } = require('../../util/crypto');
1818const { unjoiner, extender, updater, equals, insert, insertMany, markDeleted, markUndeleted, QueryOptions } = require ( '../../util/db' ) ;
1919const { resolve, reject } = require ( '../../util/promise' ) ;
2020const { splitStream } = require ( '../../util/stream' ) ;
21- const { construct, noop } = require ( '../../util/util' ) ;
21+ const { construct, noop, pickAll } = require ( '../../util/util' ) ;
2222const Option = require ( '../../util/option' ) ;
2323const Problem = require ( '../../util/problem' ) ;
2424
@@ -42,7 +42,7 @@ const fromXls = (stream, contentType, formIdFallback, ignoreWarnings) => ({ Blob
4242 } ) ;
4343
4444////////////////////////////////////////////////////////////////////////////////
45- // CREATING NEW FORMS+VERSIONS
45+ // CREATING NEW FORMS
4646
4747const _createNew = ( form , def , project , publish ) => ( { oneFirst, Actees, Forms } ) =>
4848 Actees . provision ( 'form' , project )
@@ -117,6 +117,32 @@ createNew.audit = (form, partial, _, publish) => (log) =>
117117 : null ) ) ;
118118createNew . audit . withResult = true ;
119119
120+ ////////////////////////////////////////////////////////////////////////////////
121+ // CREATING NEW VERSIONS
122+
123+ // Inserts a new form def into the database for createVersion() below, setting
124+ // fields on the def according to whether the def will be the current def or the
125+ // draft def.
126+ const _createNewDef = ( partial , form , publish , data ) => ( { one } ) => {
127+ const insertWith = ( moreData ) => one ( insert ( partial . def . with ( {
128+ formId : form . id ,
129+ xlsBlobId : partial . xls . xlsBlobId ,
130+ xml : partial . xml ,
131+ ...data ,
132+ ...moreData
133+ } ) ) ) ;
134+
135+ if ( publish === true ) return insertWith ( { publishedAt : new Date ( ) } ) ;
136+
137+ // Check whether there is an existing draft that we have access to. If not,
138+ // generate a draft token.
139+ if ( form . def . id == null || form . def . id !== form . draftDefId )
140+ return insertWith ( { draftToken : generateToken ( ) } ) ;
141+
142+ // Copy forward fields from the existing draft.
143+ return insertWith ( pickAll ( [ 'draftToken' , 'enketoId' ] , form . def ) ) ;
144+ } ;
145+
120146// creates a new version (formDef) of an existing form.
121147//
122148// if publish is true, the new version supplants the published (currentDefId)
@@ -126,20 +152,15 @@ createNew.audit.withResult = true;
126152// exists.
127153//
128154// if field paths/types collide, the database will complain.
129-
130- const _getDraftToken = ( form ) => {
131- if ( ( form . def . id != null ) && ( form . draftDefId === form . def . id ) ) return form . def . draftToken ;
132- return generateToken ( ) ;
133- } ;
134-
155+ //
135156// Parameters:
136157// ===========
137158// partial: Partial form definition of the new version
138159// form: Form frame of existing form
139160// publish: set true if you want new version to be published
140161// duplicating: set true if copying form definition from previously uploaded definition, in that cases we don't check for structural change
141162// as user has already been warned otherwise set false
142- const createVersion = ( partial , form , publish = false , duplicating = false ) => async ( { run, one , Datasets, FormAttachments, Forms, Keys } ) => {
163+ const createVersion = ( partial , form , publish , duplicating = false ) => async ( { run, Datasets, FormAttachments, Forms, Keys } ) => {
143164 // Check xmlFormId match
144165 if ( form . xmlFormId !== partial . xmlFormId )
145166 return reject ( Problem . user . unexpectedValue ( { field : 'xmlFormId' , value : partial . xmlFormId , reason : 'does not match the form you are updating' } ) ) ;
@@ -185,20 +206,13 @@ const createVersion = (partial, form, publish = false, duplicating = false) => a
185206 }
186207 }
187208
188- // Make sure our new def is in the database, and mark it as either draft or current.
189- let def = partial . def . with ( { formId : form . id , keyId, xlsBlobId : partial . xls . xlsBlobId } ) ;
190- def = ( ( publish === true )
191- ? def . with ( { publishedAt : new Date ( ) , xml : partial . xml } )
192- : def . with ( { draftToken : _getDraftToken ( form ) , xml : partial . xml } ) ) ;
193- const savedDef = await compose ( one , insert ) ( def ) ;
209+ const savedDef = await Forms . _createNewDef ( partial , form , publish , { schemaId, keyId } ) ;
194210
195211 // Update corresponding form
196212 await ( ( publish === true )
197213 ? Forms . _update ( form , { currentDefId : savedDef . id } )
198214 : Forms . _update ( form , { draftDefId : savedDef . id } ) ) ;
199215
200- await Forms . _updateDef ( new Form . Def ( savedDef ) , { schemaId } ) ;
201-
202216 // Prepare the form fields
203217 const ids = { formId : form . id , schemaId } ;
204218 const fieldsForInsert = new Array ( fields . length ) ;
@@ -691,7 +705,7 @@ const _newSchema = () => ({ one }) =>
691705 . then ( ( s ) => s . id ) ;
692706
693707module . exports = {
694- fromXls, _createNew, createNew, createVersion,
708+ fromXls, _createNew, createNew, _createNewDef , createVersion,
695709 publish, clearDraft,
696710 _update, update, _updateDef, del, restore, purge,
697711 clearUnneededDrafts,
0 commit comments