<commit_before>
/**
*/
XT.Model = Backbone.RelationalModel.extend(
  /** @scope XT.Model.prototype */ {

  idAttribute: "guid",

  initialize: function() {
    this.on('change', this.attributeChanged);
  },
  
  /*
  Change state.
  */
  attributeChanged: function() {
    this.set('dataState', 'updated');
  },

  /*
  Handle state change
  */
  fetch: function(options) {
    // turn off state handling
    this.off('change', this.attributeChanged);
    this.set('dataState', 'busy');
    
    // add call back to turn state handling back on
    if (options === undefined) options = {};
    var that = this;
    var success = options.success;
    options.success = function(resp, status, xhr) {
      that.on('change', that.attributeChanged);
      if (success) success(model, resp, options);
    };
  
    return Backbone.Model.prototype.fetch.call(this, options);
  },
  
  /*
  Sync to xtuple datasource.
  */
  sync: function(method, model, options) {
    var recordType = model.recordType;
    var id = options.id || this.id;
    var data = new XT.Data();
    var success = options.success;
    var error = options.error;
    
    if (method === 'read' && recordType && id && success) {
      return data.retrieveRecord(recordType, id, success, error);
    }
    
    return false;
  },
  
  /*
  Validate all required fields if no attributes specified.
  */
  validate: function(attributes, options) {
    if (!attributes) { // all<commit_msg>More progress on state control.<commit_after>
/**
  @class
  
  To create a new model include 'insert' in the options like so:  
    m = XT.Model({recordType: XM.Contact}, {insert: true});
    
  To load an existing record include a guid in the options like so:
    m = XT.Model({recordType: XM.Contact, guid: 1});
    m.fetch();
    
    OR
  
    m = XT.Model({recordType: XM.Contact});
    m.fetch({id: 1});
  
  @extends Backbone.RelationalModel
*/
XT.Model = Backbone.RelationalModel.extend(
  /** @scope XT.Model.prototype */ {

  idAttribute: "guid",
  
  /**
  Specify the name of a data source model here.
  */
  recordType: null,
  
  initialize: function() {
    // initialize state for inserted record
    if (arguments[1] && arguments[1].insert) {
      this.attributes.dataState = 'inserted';
    }
  },
  
  /*
  Change state.
  */
  attributeChanged: function() {
    if (this.get('dataState') === 'read') {
      this.set('dataState', 'updated');
    }
  },
  
  /* 
  A model is new if the dataState is "inserted".
  */
  isNew: function() {
    return this.get('dataState') === 'inserted';
  },

  /*
  Handle state change
  */
  fetch: function(options) {
    // turn off state handling
    this.off('change', this.attributeChanged);
    
    // add call back to turn state handling back on after fetch
    if (options === undefined) options = {};
    var that = this;
    var success = options.success;
    options.success = function(resp, status, xhr) {
      that.on('change', that.attributeChanged);
      if (success) success(model, resp, options);
    };
  
    return Backbone.Model.prototype.fetch.call(this, options);
  },
  
  destroy: function(options) {
    this.set('dataState', 'deleted');
    return Backbone.Model.prototype.destroy.call(this, options);
  },
  
  /*
  Sync to xtuple datasource.
  */
  sync: function(method, model, options) {
    var recordType = model.recordType;
    var id = options.id || this.id;
    var data = new XT.Data();
    var success = options.success;
    var error = options.error;
    
    if (method === 'read' && recordType && id && success) {
      return data.retrieveRecord(recordType, id, success, error);
    }
    
    return false;
  },
  
  /*
  Validate all required fields if no attributes specified.
  */
  validate: function(attributes, options) {
    if (this.get('dataState') === 'deleted') {
      return 'Can not alter deleted record';
    }
    
    if (!attributes) { // all
{'fraction_non_alphanumeric': 0.14256515074092999, 'fraction_numerical': 0.001021972406745018, 'mean_word_length': 2.689915174363808, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1270543', 'n_tokens_mistral': 1230, 'n_tokens_neox': 1221, 'n_words': 330}