// PropertyGroupsProcess model
// Allows cumulation certain subset of property groups (form sections)

'use strict';

var memoize               = require('memoizee/plain')
  , definePercentage      = require('dbjs-ext/number/percentage')
  , defineUInteger        = require('dbjs-ext/number/integer/u-integer')
  , defineMultipleProcess = require('./multiple-process')
  , defineFormSectionBase = require('../form-section-base');

module.exports = memoize(function (db/*, options*/) {
	var Percentage      = definePercentage(db)
	  , UInteger        = defineUInteger(db)
	  , MultipleProcess = defineMultipleProcess(db)
	  , FormSectionBase = defineFormSectionBase(db);

	var PropertyGroupsProcess = MultipleProcess.extend('PropertyGroupsProcess', {
		// Applicable form sections
		applicable: { type: FormSectionBase },
		// Cumulated progress of all applicable form sections
		progress: { type: Percentage, value: function (_observe) {
			var total = 0, valid = 0;
			this.applicable.forEach(function (section) {
				var weight = _observe(section._weight), status = _observe(section._status);
				if (!weight) {
					if (status !== 1) ++total;
					return;
				}
				valid += status * weight;
				total += weight;
			});
			if (!total) return 1;
			return valid / total;
		} },
		// Weight of property group (in other words: number of required properties)
		weight: { type: UInteger, value: function (_observe) {
			var weight = 0;
			this.applicable.forEach(function (section) { weight += _observe(section._weight); });
			return weight;
		} },

		toJSON: { type: db.Function, value: function (ignore) {
			var result = [];
			this.applicable.forEach(function (section) {
				if (section.hasFilledPropertyNamesDeep) result.push(section.toJSON());
			});
			return result;
		} }
	});
	PropertyGroupsProcess.prototype.map._descriptorPrototype_.type = FormSectionBase;
	return PropertyGroupsProcess;
}, { normalizer: require('memoizee/normalizers/get-1')() });

@@ -114,16 +114,79 @@
 t';%0A%0Avar
+ _                     = require('mano').i18n.bind('Model')%0A  ,
  memoize
@@ -228,16 +228,63 @@
 plain')%0A
+  , Map                   = require('es6-map')%0A
   , defi
@@ -414,16 +414,143 @@
 teger')%0A
+  , defineStringLine      = require('dbjs-ext/string/string-line')%0A  , defineCreateEnum      = require('dbjs-ext/create-enum')%0A
   , defi
@@ -797,24 +797,68 @@
 Integer(db)%0A
+%09  , StringLine      = defineStringLine(db)%0A
 %09  , Multipl
@@ -945,16 +945,232 @@
 e(db);%0A%0A
+%09defineCreateEnum(db);%0A%0A%09// Enum for forms status%0A%09var PropertyGroupsStatus = StringLine.createEnum('PropertyGroupsStatus', new Map(%5B%0A%09%09%5B'valid', %7B label: _(%22Valid%22) %7D%5D,%0A%09%09%5B'invalid', %7B label: _(%22Invalid%22) %7D%5D%0A%09%5D));%0A%0A
 %09var Pro
@@ -2009,24 +2009,24 @@
 eight); %7D);%0A
-
 %09%09%09return we
@@ -2037,16 +2037,459 @@
 ;%0A%09%09%7D %7D,
+%0A%09%09// Verification status of process%0A%09%09status: %7B type: PropertyGroupsStatus %7D,%0A%09%09// Eventual rejection details%0A%09%09rejectReason: %7B type: db.String, required: true, label: _(%22Explanation%22) %7D,%0A%09%09// Whether process was rejected and reject reason was provided%0A%09%09isRejected: %7B type: db.Boolean, value: function () %7B%0A%09%09%09if (this.status == null) return false;%0A%09%09%09if (this.status !== 'invalid') return false;%0A%09%09%09return Boolean(this.rejectReason);%0A%09%09%7D %7D,
 %0A%0A%09%09toJS

Add status, rejectReason and isRejected to PropertyGroupsProcess