(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else {
		var a = factory();
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 731);
/******/ })
/************************************************************************/
/******/ ({

/***/ 0:
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function(useSourceMap) {
	var list = [];

	// return the list of modules as css string
	list.toString = function toString() {
		return this.map(function (item) {
			var content = cssWithMappingToString(item, useSourceMap);
			if(item[2]) {
				return "@media " + item[2] + "{" + content + "}";
			} else {
				return content;
			}
		}).join("");
	};

	// import a list of modules into the list
	list.i = function(modules, mediaQuery) {
		if(typeof modules === "string")
			modules = [[null, modules, ""]];
		var alreadyImportedModules = {};
		for(var i = 0; i < this.length; i++) {
			var id = this[i][0];
			if(typeof id === "number")
				alreadyImportedModules[id] = true;
		}
		for(i = 0; i < modules.length; i++) {
			var item = modules[i];
			// skip already imported module
			// this implementation is not 100% perfect for weird media query combinations
			//  when a module is imported multiple times with different media queries.
			//  I hope this will never occur (Hey this way we have smaller bundles)
			if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
				if(mediaQuery && !item[2]) {
					item[2] = mediaQuery;
				} else if(mediaQuery) {
					item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
				}
				list.push(item);
			}
		}
	};
	return list;
};

function cssWithMappingToString(item, useSourceMap) {
	var content = item[1] || '';
	var cssMapping = item[3];
	if (!cssMapping) {
		return content;
	}

	if (useSourceMap && typeof btoa === 'function') {
		var sourceMapping = toComment(cssMapping);
		var sourceURLs = cssMapping.sources.map(function (source) {
			return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
		});

		return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
	}

	return [content].join('\n');
}

// Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
	// eslint-disable-next-line no-undef
	var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
	var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;

	return '/*# ' + data + ' */';
}


/***/ }),

/***/ 1:
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

var stylesInDom = {};

var	memoize = function (fn) {
	var memo;

	return function () {
		if (typeof memo === "undefined") memo = fn.apply(this, arguments);
		return memo;
	};
};

var isOldIE = memoize(function () {
	// Test for IE <= 9 as proposed by Browserhacks
	// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
	// Tests for existence of standard globals is to allow style-loader
	// to operate correctly into non-standard environments
	// @see https://github.com/webpack-contrib/style-loader/issues/177
	return window && document && document.all && !window.atob;
});

var getElement = (function (fn) {
	var memo = {};

	return function(selector) {
		if (typeof memo[selector] === "undefined") {
			var styleTarget = fn.call(this, selector);
			// Special case to return head of iframe instead of iframe itself
			if (styleTarget instanceof window.HTMLIFrameElement) {
				try {
					// This will throw an exception if access to iframe is blocked
					// due to cross-origin restrictions
					styleTarget = styleTarget.contentDocument.head;
				} catch(e) {
					styleTarget = null;
				}
			}
			memo[selector] = styleTarget;
		}
		return memo[selector]
	};
})(function (target) {
	return document.querySelector(target)
});

var singleton = null;
var	singletonCounter = 0;
var	stylesInsertedAtTop = [];

var	fixUrls = __webpack_require__(2);

module.exports = function(list, options) {
	if (typeof DEBUG !== "undefined" && DEBUG) {
		if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};

	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (!options.singleton) options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
	if (!options.insertInto) options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (!options.insertAt) options.insertAt = "bottom";

	var styles = listToStyles(list, options);

	addStylesToDom(styles, options);

	return function update (newList) {
		var mayRemove = [];

		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];

			domStyle.refs--;
			mayRemove.push(domStyle);
		}

		if(newList) {
			var newStyles = listToStyles(newList, options);
			addStylesToDom(newStyles, options);
		}

		for (var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];

			if(domStyle.refs === 0) {
				for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();

				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom (styles, options) {
	for (var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];

		if(domStyle) {
			domStyle.refs++;

			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}

			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];

			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}

			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles (list, options) {
	var styles = [];
	var newStyles = {};

	for (var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = options.base ? item[0] + options.base : item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};

		if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
		else newStyles[id].parts.push(part);
	}

	return styles;
}

function insertStyleElement (options, style) {
	var target = getElement(options.insertInto)

	if (!target) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}

	var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];

	if (options.insertAt === "top") {
		if (!lastStyleElementInsertedAtTop) {
			target.insertBefore(style, target.firstChild);
		} else if (lastStyleElementInsertedAtTop.nextSibling) {
			target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			target.appendChild(style);
		}
		stylesInsertedAtTop.push(style);
	} else if (options.insertAt === "bottom") {
		target.appendChild(style);
	} else if (typeof options.insertAt === "object" && options.insertAt.before) {
		var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
		target.insertBefore(style, nextSibling);
	} else {
		throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
	}
}

function removeStyleElement (style) {
	if (style.parentNode === null) return false;
	style.parentNode.removeChild(style);

	var idx = stylesInsertedAtTop.indexOf(style);
	if(idx >= 0) {
		stylesInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement (options) {
	var style = document.createElement("style");

	options.attrs.type = "text/css";

	addAttrs(style, options.attrs);
	insertStyleElement(options, style);

	return style;
}

function createLinkElement (options) {
	var link = document.createElement("link");

	options.attrs.type = "text/css";
	options.attrs.rel = "stylesheet";

	addAttrs(link, options.attrs);
	insertStyleElement(options, link);

	return link;
}

function addAttrs (el, attrs) {
	Object.keys(attrs).forEach(function (key) {
		el.setAttribute(key, attrs[key]);
	});
}

function addStyle (obj, options) {
	var style, update, remove, result;

	// If a transform function was defined, run it on the css
	if (options.transform && obj.css) {
	    result = options.transform(obj.css);

	    if (result) {
	    	// If transform returns a value, use that instead of the original css.
	    	// This allows running runtime transformations on the css.
	    	obj.css = result;
	    } else {
	    	// If the transform function returns a falsy value, don't add this css.
	    	// This allows conditional loading of css
	    	return function() {
	    		// noop
	    	};
	    }
	}

	if (options.singleton) {
		var styleIndex = singletonCounter++;

		style = singleton || (singleton = createStyleElement(options));

		update = applyToSingletonTag.bind(null, style, styleIndex, false);
		remove = applyToSingletonTag.bind(null, style, styleIndex, true);

	} else if (
		obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function"
	) {
		style = createLinkElement(options);
		update = updateLink.bind(null, style, options);
		remove = function () {
			removeStyleElement(style);

			if(style.href) URL.revokeObjectURL(style.href);
		};
	} else {
		style = createStyleElement(options);
		update = applyToTag.bind(null, style);
		remove = function () {
			removeStyleElement(style);
		};
	}

	update(obj);

	return function updateStyle (newObj) {
		if (newObj) {
			if (
				newObj.css === obj.css &&
				newObj.media === obj.media &&
				newObj.sourceMap === obj.sourceMap
			) {
				return;
			}

			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;

		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag (style, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (style.styleSheet) {
		style.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = style.childNodes;

		if (childNodes[index]) style.removeChild(childNodes[index]);

		if (childNodes.length) {
			style.insertBefore(cssNode, childNodes[index]);
		} else {
			style.appendChild(cssNode);
		}
	}
}

function applyToTag (style, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		style.setAttribute("media", media)
	}

	if(style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		while(style.firstChild) {
			style.removeChild(style.firstChild);
		}

		style.appendChild(document.createTextNode(css));
	}
}

function updateLink (link, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/*
		If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
		and there is no publicPath defined then lets turn convertToAbsoluteUrls
		on by default.  Otherwise default to the convertToAbsoluteUrls option
		directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls) {
		css = fixUrls(css);
	}

	if (sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = link.href;

	link.href = URL.createObjectURL(blob);

	if(oldSrc) URL.revokeObjectURL(oldSrc);
}


/***/ }),

/***/ 166:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Division edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.DivisionEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Division Edit Dialog</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.DivisionGridPanel
 */
Tine.Sales.DivisionEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    windowWidth: 650,
    windowHeight: 450,
    
    /**
     * called on multiple edit
     * @return {Boolean}
     */
    isMultipleValid: function() {
        return true;
    },
    
    /**
     * @see: Tine.widgets.dialog.EditDialog.onRecordLoad
     */
    onRecordLoad: function() {
        Tine.Sales.DivisionEditDialog.superclass.onRecordLoad.call(this);
        
        if (! this.copyRecord && ! this.record.id) {
            this.window.setTitle(this.app.i18n._('Add New Division'));
        }
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            defaults: {
                hideMode: 'offsets'
            },
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Division', 'Divisions', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: 1
                    },
                    items: [[{
                        fieldLabel: this.app.i18n._('Title'),
                        name: 'title',
                        allowBlank: false
                    }]
                    ]
                }]
            }, new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: 'Sales_Model_Division'
            })]
        };
    }
});


/***/ }),

/***/ 167:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M12.3,33.1c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7s0.2,1.2,0.7,1.7 c0.5,0.5,1,0.7,1.7,0.7c0.7,0,1.2-0.2,1.7-0.7C12,34.4,12.3,33.8,12.3,33.1z M19.6,33.1c0-0.7-0.2-1.2-0.7-1.7 c-0.5-0.5-1-0.7-1.7-0.7c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7s0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7 c0.7,0,1.2-0.2,1.7-0.7C19.3,34.4,19.6,33.8,19.6,33.1z M12.3,25.8c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7 c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7s0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7c0.7,0,1.2-0.2,1.7-0.7 C12,27.1,12.3,26.5,12.3,25.8z M26.8,33.1c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7s-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7 s0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7s1.2-0.2,1.7-0.7C26.6,34.4,26.8,33.8,26.8,33.1z M19.6,25.8c0-0.7-0.2-1.2-0.7-1.7 c-0.5-0.5-1-0.7-1.7-0.7c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7s0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7 c0.7,0,1.2-0.2,1.7-0.7C19.3,27.1,19.6,26.5,19.6,25.8z M12.3,18.6c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7 c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7c0,0.7,0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7c0.7,0,1.2-0.2,1.7-0.7 C12,19.8,12.3,19.2,12.3,18.6z M26.8,25.8c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7s-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7 s0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7s1.2-0.2,1.7-0.7C26.6,27.1,26.8,26.5,26.8,25.8z M19.6,18.6c0-0.7-0.2-1.2-0.7-1.7 c-0.5-0.5-1-0.7-1.7-0.7c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7c0,0.7,0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7 c0.7,0,1.2-0.2,1.7-0.7C19.3,19.8,19.6,19.2,19.6,18.6z M34.1,33.1v-7.3c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7 s-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7v7.3c0,0.7,0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7s1.2-0.2,1.7-0.7 C33.9,34.4,34.1,33.8,34.1,33.1z M26.8,18.6c0-0.7-0.2-1.2-0.7-1.7c-0.5-0.5-1-0.7-1.7-0.7s-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7 c0,0.7,0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7s1.2-0.2,1.7-0.7C26.6,19.8,26.8,19.2,26.8,18.6z M34.1,12.5V7.6 c0-0.3-0.1-0.6-0.4-0.9c-0.2-0.2-0.5-0.4-0.9-0.4H8.6C8.3,6.4,8,6.5,7.8,6.8C7.5,7,7.4,7.3,7.4,7.6v4.9c0,0.3,0.1,0.6,0.4,0.9 s0.5,0.4,0.9,0.4h24.3c0.3,0,0.6-0.1,0.9-0.4C34,13.1,34.1,12.8,34.1,12.5z M34.1,18.6c0-0.7-0.2-1.2-0.7-1.7 c-0.5-0.5-1-0.7-1.7-0.7s-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1-0.7,1.7c0,0.7,0.2,1.2,0.7,1.7c0.5,0.5,1,0.7,1.7,0.7s1.2-0.2,1.7-0.7 C33.9,19.8,34.1,19.2,34.1,18.6z M36.6,6.4v29.1c0,0.7-0.2,1.2-0.7,1.7c-0.5,0.5-1,0.7-1.7,0.7H7.4c-0.7,0-1.2-0.2-1.7-0.7 c-0.5-0.5-0.7-1-0.7-1.7V6.4c0-0.7,0.2-1.2,0.7-1.7S6.8,4,7.4,4h26.7c0.7,0,1.2,0.2,1.7,0.7C36.3,5.2,36.6,5.8,36.6,6.4z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 168:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M28.4,24.9c0.1,0.1,0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H14.6c-0.2,0-0.3-0.1-0.4-0.2 C14,26.9,14,26.7,14,26.5v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h13.4C28.1,24.7,28.3,24.8,28.4,24.9z M27.9,29.6H14.6 c-0.2,0-0.3,0.1-0.4,0.2C14,29.9,14,30,14,30.2v1.2c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.3,0.2,0.4,0.2h13.4c0.2,0,0.3-0.1,0.4-0.2 c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C28.3,29.6,28.1,29.6,27.9,29.6z M21.8,18.8c0.1-0.2,0.2-0.3,0.2-0.5 c0-0.3-0.2-0.6-0.5-0.7c-0.2-0.1-0.4-0.2-0.5-0.2c-0.3,0-0.7,0.2-0.8,0.6l0,0c-0.5,1.2-1.7,2-2.8,2c-0.9,0-1.7-0.4-2.3-1.1h2 c0.2,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.4,0.3-0.7c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2.8c0-0.2-0.1-0.4-0.1-0.7 c0-0.2,0-0.4,0.1-0.6h2.8c0.2,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.4,0.3-0.7c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2 c0.6-0.8,1.4-1.2,2.4-1.2c1.1,0,2.2,0.7,2.8,2l0,0.1l0,0c0.2,0.2,0.5,0.4,0.8,0.4c0.1,0,0.2,0,0.4-0.1l0.1,0l0.1-0.1 c0.2-0.2,0.4-0.5,0.4-0.8c0-0.1,0-0.2-0.1-0.4l0,0l0,0c-0.8-1.9-2.6-3.1-4.4-3.1c-2.1,0-3.8,1.3-4.6,3.2h-1c-0.2,0-0.5,0.1-0.7,0.3 c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.2,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3h0.6c0,0.1,0,0.3,0,0.4c0,0.3,0,0.5,0.1,0.8h-0.6 c-0.2,0-0.5,0.1-0.7,0.3c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.2,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3H13c0.9,1.7,2.5,2.9,4.4,2.9 C19.3,21.6,21,20.5,21.8,18.8L21.8,18.8C21.8,18.9,21.8,18.8,21.8,18.8C21.8,18.8,21.8,18.8,21.8,18.8L21.8,18.8z M34.6,11.2 c0.4,0.4,0.7,0.8,0.9,1.4c0.3,0.6,0.4,1.2,0.4,1.7v21.9c0,0.5-0.2,0.9-0.5,1.3S34.5,38,34,38H8.5c-0.5,0-0.9-0.2-1.3-0.5 c-0.4-0.4-0.5-0.8-0.5-1.3V5.8c0-0.5,0.2-0.9,0.5-1.3C7.6,4.2,8,4,8.5,4h17c0.5,0,1.1,0.1,1.7,0.4c0.6,0.3,1.1,0.6,1.4,0.9 L34.6,11.2z M26.1,6.6v7.1h7.1c-0.1-0.4-0.3-0.6-0.4-0.8L26.9,7C26.7,6.8,26.5,6.7,26.1,6.6z M33.4,35.6V16.2h-7.9 c-0.5,0-0.9-0.2-1.3-0.5c-0.4-0.4-0.5-0.8-0.5-1.3V6.4H9.1v29.2H33.4z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 2:
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ }),

/***/ 731:
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(732);
__webpack_require__(733);
__webpack_require__(734);
__webpack_require__(735);
__webpack_require__(736);
__webpack_require__(737);
__webpack_require__(738);
__webpack_require__(739);
__webpack_require__(740);
__webpack_require__(166);
__webpack_require__(741);
__webpack_require__(742);
__webpack_require__(743);
__webpack_require__(744);
__webpack_require__(745);
__webpack_require__(166);
__webpack_require__(746);
__webpack_require__(747);
__webpack_require__(748);
__webpack_require__(749);
__webpack_require__(750);
__webpack_require__(751);
__webpack_require__(752);
__webpack_require__(753);
__webpack_require__(754);
__webpack_require__(755);
__webpack_require__(756);
__webpack_require__(757);
__webpack_require__(758);
__webpack_require__(759);
__webpack_require__(760);
__webpack_require__(761);
__webpack_require__(762);
__webpack_require__(763);
__webpack_require__(764);
__webpack_require__(765);
__webpack_require__(766);
__webpack_require__(767);
__webpack_require__(768);
__webpack_require__(769);
__webpack_require__(770);
__webpack_require__(771);
__webpack_require__(772);
__webpack_require__(773);
__webpack_require__(774);
__webpack_require__(775);
__webpack_require__(776);
__webpack_require__(777);
__webpack_require__(778);
__webpack_require__(779);
__webpack_require__(780);
__webpack_require__(781);
__webpack_require__(782);


/***/ }),

/***/ 732:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * address renderer, not a default renderer
 * 
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * 
 * @constructor
 * Constructs mainscreen of the Sales application
 */
Tine.Sales.MainScreen = Ext.extend(Tine.widgets.MainScreen, {
    appName: 'Sales',
    activeContentType: 'Product',
    contentTypes: [
        {modelName: 'Product', requiredRight: 'manage_products', singularContainerMode: true},
        {modelName: 'Contract', requiredRight: 'manage_contracts', singularContainerMode: true, genericCtxActions: ['grants']},
        {modelName: 'Customer', requiredRight: 'manage_customers', singularContainerMode: true},
        {modelName: 'Supplier', requiredRight: 'manage_suppliers', singularContainerMode: true},
        {modelName: 'Invoice', requiredRight: 'manage_invoices', singularContainerMode: true},
        {modelName: 'PurchaseInvoice', requiredRight: 'manage_purchase_invoices', singularContainerMode: true},
        {modelName: 'CostCenter', requiredRight: 'manage_costcenters', singularContainerMode: true},
        {modelName: 'Division', requiredRight: 'manage_divisions', singularContainerMode: true},
        {modelName: 'Offer', requiredRight: 'manage_offers', singularContainerMode: true},
        {modelName: 'OrderConfirmation', requiredRight: 'manage_orderconfirmations', singularContainerMode: true}
    ]
});

// rendered sums registry for the invoiceposition grid panel
Tine.Sales.renderedSumsPerMonth = {};

Tine.Sales.addToClipboard = function(record, companyName) {
    // this is called either from the edit dialog or from the grid, so we have different record types
    var fieldPrefix = record.data.hasOwnProperty('bic') ? 'adr_' : '';
    
    companyName = companyName ? companyName : (record.get('name') ? record.get('name') : '');

    var lines = companyName + "\n";
    
        lines += (record.get((fieldPrefix + 'prefix1')) ? record.get((fieldPrefix + 'prefix1')) + "\n" : '');
        lines += (record.get((fieldPrefix + 'prefix2')) ? record.get((fieldPrefix + 'prefix2')) + "\n" : '');
        lines += (record.get(fieldPrefix + 'pobox') ? record.get(fieldPrefix + 'pobox') + "\n" : (record.get(fieldPrefix + 'street') ? record.get(fieldPrefix + 'street') + "\n" : ''));
        lines += (record.get((fieldPrefix + 'postalcode')) ? (record.get((fieldPrefix + 'postalcode')) + ' ') : '') + (record.get((fieldPrefix + 'locality')) ? record.get((fieldPrefix + 'locality')) : '');
        
        if (record.get('countryname')) {
            lines += "\n" + record.get('countryname');
        }
    
    var app = Tine.Tinebase.appMgr.get('Sales');
    
    Tine.Sales.CopyAddressDialog.openWindow({winTitle: app.i18n._('Copy address to the clipboard'), app: app, content: lines});
};

/** @param {Tine.Tinebase.data.Record} record
 * @param {String} companyName
 * 
 * @return {String}
 */
Tine.Sales.renderAddress = function(record, companyName) {
    // this is called either from the edit dialog or from the grid, so we have different record types
    var fieldPrefix = record.data.hasOwnProperty('bic') ? 'adr_' : '';
    
    companyName = companyName ? companyName : (record.get('name') ? record.get('name') : '');

    var lines = companyName + "\n";
    
    lines += (record.get((fieldPrefix + 'prefix1')) ? record.get((fieldPrefix + 'prefix1')) + "\n" : '');
    lines += (record.get((fieldPrefix + 'prefix2')) ? record.get((fieldPrefix + 'prefix2')) + "\n" : '');
    lines += (record.get((fieldPrefix + 'pobox')) ? (record.get(fieldPrefix + 'pobox') + "\n") : ((record.get(fieldPrefix + 'street') ? record.get(fieldPrefix + 'street') + "\n" : '')));
    lines += (record.get((fieldPrefix + 'postalcode')) ? (record.get((fieldPrefix + 'postalcode')) + ' ') : '') + (record.get((fieldPrefix + 'locality')) ? record.get((fieldPrefix + 'locality')) : '');
    
    if (record.get('countryname')) {
        lines += "\n" + record.get('countryname');
    }
    
    return lines;
};

/**
 * opens the Copy Address Dialog and adds the rendered address
 * 
 * @param {Tine.Tinebase.data.Record} record
 * @param {String} companyName
 */
Tine.Sales.addToClipboard = function(record, companyName) {
    var app = Tine.Tinebase.appMgr.get('Sales');
    
    Tine.Sales.CopyAddressDialog.openWindow({
        winTitle: 'Copy address to the clipboard', 
        app: app, 
        content: Tine.Sales.renderAddress(record, companyName)
    });
};

Tine.Sales.renderAddressAsLine = function(values) {
    var ret = '';
    var app = Tine.Tinebase.appMgr.get('Sales');
    if (values.customer_id && values.customer_id.hasOwnProperty('name')) {
        ret += '<b>' + Ext.util.Format.htmlEncode(values.customer_id.name) + '</b> - ';
    }
    
    ret += Ext.util.Format.htmlEncode((values.postbox ? values.postbox : values.street));
    ret += ', ';
    ret += Ext.util.Format.htmlEncode(values.postalcode);
    ret += ' ';
    ret += Ext.util.Format.htmlEncode(values.locality);
    ret += ' (';
    ret += app.i18n._(values.type)
    
    if (values.type == 'billing') {
        ret += ' - ' + Ext.util.Format.htmlEncode(values.custom1);
    }
    
    ret += ')';
    
    return ret;
};

/**
 * register special renderer for invoice address_id
 */
Tine.widgets.grid.RendererManager.register('Sales', 'Invoice', 'address_id', Tine.Sales.renderAddressAsLine);

/**
 * renders the model of the invoice position
 * 
 * @param {String} value
 * @param {Object} row
 * @param {Tine.Tinebase.data.Record} rec
 * @return {String}
 */
Tine.Sales.renderInvoicePositionModel = function(value, row, rec) {
    if (! value) {
        return '';
    }
    var split = value.split('_Model_');
    var model = Tine[split[0]].Model[split[1]];
    
    return '<span class="tine-recordclass-gridicon ' + model.getMeta('appName') + model.getMeta('modelName') + '">&nbsp;</span>' + model.getRecordName() + ' (' + model.getAppName() + ')';
};

/**
 * register special renderer for the invoice position
 */
Tine.widgets.grid.RendererManager.register('Sales', 'InvoicePosition', 'model', Tine.Sales.renderInvoicePositionModel);

/**
 * renders the quantity of the invoice position
 */
Tine.Sales.InvoicePositionQuantityRendererRegistry = function() {
    var renderers = {};
    
    return {
        /**
         * return renderer
         * 
         * @param {String} phpModelName
         * @return {Function}
         */
        get: function(phpModelName, unit) {
            var unit = unit.replace(/\s/, '');
            if (renderers.hasOwnProperty(phpModelName+unit)) {
                return renderers[phpModelName+unit];
            } else {
                // default function
                return function(value, row, rec) {
                    return value;
                }
            }
        },
        
        /**
         * register renderer
         * 
         * @param {String} phpModelName
         * @param {Function} func
         */
        register: function(phpModelName, unit, func) {
            var unit = unit.replace(/\s/, '');
            renderers[phpModelName+unit] = func;
        },
        
        /**
         * check if a renderer is explicitly registered
         * 
         * @param {String} phpModelName
         * @return {Boolean}
         */
        has: function(phpModelName, unit) {
            var unit = unit.replace(/\s/, '');
            return renderers.hasOwnProperty(phpModelName+unit);
        }
    }
}();

/**
 * renders the unit of the invoice position
 * 
 * @param {String} value
 * @param {Object} row
 * @param {Tine.Tinebase.data.Record} rec
 * @return {String}
 */
Tine.Sales.renderInvoicePositionUnit = function(value, row, rec) {
    
    if (! value) {
        return '';
    }
    
    var model = rec.get('model');
    var split = model.split('_Model_');
    
    var app = Tine.Tinebase.appMgr.get(split[0]);
    
    return app.i18n._(value);
};
/**
 * renders the unit of the invoice position
 * @param {} value
 * @param {} row
 * @param {} rec
 * @return {}
 */
Tine.Sales.renderInvoicePositionQuantity = function(value, row, rec) {
    var model = rec.data.model;
    if (Tine.Sales.InvoicePositionQuantityRendererRegistry.has(model, rec.data.unit)) {
        var renderer = Tine.Sales.InvoicePositionQuantityRendererRegistry.get(model, rec.data.unit);
        return renderer(value, row, rec);
    } else {
        return value;
    }
};

/**
 * register special renderer for the invoice position
 */
Tine.widgets.grid.RendererManager.register('Sales', 'InvoicePosition', 'unit', Tine.Sales.renderInvoicePositionUnit);
Tine.widgets.grid.RendererManager.register('Sales', 'InvoicePosition', 'quantity', Tine.Sales.renderInvoicePositionQuantity);


Tine.Sales.renderBillingPoint = function(v) {
    var app = Tine.Tinebase.appMgr.get('Sales');
    return v ? app.i18n._hidden(v) : '';
}

Tine.widgets.grid.RendererManager.register('Sales', 'Contract', 'billing_point', Tine.Sales.renderBillingPoint);

Tine.Sales.renderCostCenter = function(value, row, rec) {
    if (Ext.isObject(value)) {
        return value.number + ' - ' + value.remark;
    }
    
    return '';
};

Tine.widgets.grid.RendererManager.register('Sales', 'Invoice', 'costcenter_id', Tine.Sales.renderCostCenter);

/**
 * allows all accountables to register (needed for accountable combo box)
 */
Tine.Sales.AccountableRegistry = function() {
    var accountables = {};
    
    return {
        /**
         * return all accountables as array
         * 
         * @return {Array}
         */
        getArray: function() {
            var ar = [];
            Ext.iterate(accountables, function(key, value) {
                ar.push(value);
            });
            
            return ar;
        },
        
        /**
         * register accountable
         * 
         * @param {String} appName
         * @param {String} modelName
         */
        register: function(appName, modelName) {
            var key = appName + modelName;
            if (! accountables.hasOwnProperty(key)) {
                accountables[key] = {appName: appName, modelName: modelName};
            }
        },
        
        /**
         * check if a renderer is explicitly registered
         * 
         * @param {String} appName
         * @param {String} modelName
         * @return {Boolean}
         */
        has: function(appName, modelName) {
            var key = appName + modelName;
            return accountables.hasOwnProperty(key);
        }
    }
}();

Tine.Sales.AccountableRegistry.register('Sales', 'Product');


Tine.Sales.renderAccountable = function(values) {
    if (Ext.isEmpty(values)) {
        return '';
    }
    var split = values.split('_Model_');
    var ret = '';
    var app = Tine.Tinebase.appMgr.get(split[0]);
    
    return app ? app.i18n._(split[0] + split[1]) : null;
};

/**
 * register special renderer for invoice address_id
 */
Tine.widgets.grid.RendererManager.register('Sales', 'Product', 'accountable', Tine.Sales.renderAccountable);


/***/ }),

/***/ 733:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2009-2015 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.AdminPanel
 * @extends     Ext.FormPanel
 * @author      Alexander Stintzing <alex@stintzing.net>
 */
Tine.Sales.AdminPanel = Ext.extend(Ext.FormPanel, {
    appName : 'Sales',

    layout : 'fit',
    border : false,
    cls : 'tw-editdialog',

    labelAlign : 'top',

    anchor : '100% 100%',
    deferredRender : false,
    buttonAlign : null,
    bufferResize : 500,

    /**
     * init component
     */
    initComponent: function() {

        if (!this.app) {
            this.app = Tine.Tinebase.appMgr.get(this.appName);
        }

        Tine.log.debug('initComponent: appName: ', this.appName);
        Tine.log.debug('initComponent: app: ', this.app);

        // init actions
        this.initActions();
        // init buttons and tbar
        this.initButtons();

        // get items for this dialog
        this.items = this.getFormItems();
        
        Tine.Sales.AdminPanel.superclass.initComponent.call(this);
    },

    /**
     * init actions
     */
    initActions: function() {
        this.action_cancel = new Ext.Action({
            text : this.app.i18n._('Cancel'),
            minWidth : 70,
            scope : this,
            handler : this.onCancel,
            iconCls : 'action_cancel'
        });

        this.action_update = new Ext.Action({
            text : this.app.i18n._('OK'),
            minWidth : 70,
            scope : this,
            handler : this.onUpdate,
            iconCls : 'action_saveAndClose'
        });
    },

    /**
     * init buttons
     */
    initButtons : function() {
        this.fbar = [ '->', this.action_cancel, this.action_update ];
    },  

    /**
     * is called when the component is rendered
     * @param {} ct
     * @param {} position
     */
    onRender : function(ct, position) {
        this.loadMask = new Ext.LoadMask(ct, {msg: i18n._('Loading...')});
        Tine.Sales.AdminPanel.superclass.onRender.call(this, ct, position);

        // generalized keybord map for edit dlgs
        var map = new Ext.KeyMap(this.el, [ {
            key : [ 10, 13 ], // ctrl + return
            ctrl : true,
            fn : this.onUpdate,
            scope : this
        } ]);

    },
    
    /**
     * closes the window
     */
    onCancel: function() {
        this.fireEvent('cancel');
        this.purgeListeners();
        this.window.close();
    },

    /**
     * save record and close window
     */
    onUpdate : function() {
        Ext.Ajax.request({
            url: 'index.php',
            scope: this,
            params: {
                method: 'Sales.setConfig',
                config: this.getForm().getFieldValues(),
            },
            success : function(_result, _request) {
                this.loadMask.hide();
                // reload mainscreen to make sure registry gets updated
                window.location = window.location.href.replace(/#+.*/, '');
            },
            failure: function(result) {
                Tine.Tinebase.ExceptionHandler.handleRequestException(result)
            }
        });
    },

    /**
     * create and return form items
     * @return Object
     */
    getFormItems: function() {
        var config = Tine.Sales.registry.get('config');

        var currency = [
            ['EUR', this.app.i18n._('Euro (€)')]
        ];

        var currencyStore = new Ext.data.ArrayStore({
            fields: [
                'currency_id',
                'currency'
            ],
            data: currency,
            disabled: false
        });


        return {
            border: false,
            frame : false,
            layout: 'border',

            items: [{
                region: 'center',
                border: false,
                frame : false,
                
                xtype       : 'columnform',
                labelAlign  : 'top',
                formDefaults: {
                    xtype         :'textfield',
                    anchor        : '100%',
                    labelSeparator: '',
                    columnWidth   : 1/3
                },
                items: [
                    [
                        {
                            fieldLabel: this.app.i18n._(config.ownCurrency.definition.label),
                            name      : 'ownCurrency',
                            value     : config.ownCurrency.value ? config.ownCurrency.value : config.ownCurrency['default'],
                            xtype     : 'combo',
                            mode      : 'local',
                            scope     : this,
                            valueField: 'currency_id',
                            displayField: 'currency',
                            store     : currencyStore
                        }
                    ], [
                        {
                            fieldLabel: this.app.i18n._(config.contractNumberGeneration.definition.label),
                            name      : 'contractNumberGeneration',
                            value     : config.contractNumberGeneration.value ? config.contractNumberGeneration.value : config.contractNumberGeneration['default'],
                            xtype     : 'combo',
                            mode      : 'local',
                            forceSelection: true,
                            triggerAction: 'all',
                            store     : config.contractNumberGeneration.definition.options
                        }, {
                            fieldLabel: this.app.i18n._(config.contractNumberValidation.definition.label),
                            name      : 'contractNumberValidation',
                            value     : config.contractNumberValidation.value ? config.contractNumberValidation.value : config.contractNumberValidation['default'],
                            xtype     : 'combo',
                            mode      : 'local',
                            forceSelection: true,
                            triggerAction: 'all',
                            store     : config.contractNumberValidation.definition.options
                        }
                    ], [
                        {
                            fieldLabel: this.app.i18n._(config.productNumberGeneration.definition.label),
                            name      : 'productNumberGeneration',
                            value     : config.productNumberGeneration.value ? config.productNumberGeneration.value : config.productNumberGeneration['default'],
                            xtype     : 'combo',
                            mode      : 'local',
                            forceSelection: true,
                            triggerAction: 'all',
                            store     : config.productNumberGeneration.definition.options
                        }, {
                            fieldLabel: this.app.i18n._(config.productNumberValidation.definition.label),
                            name      : 'productNumberValidation',
                            value     : config.productNumberValidation.value ? config.productNumberValidation.value : config.productNumberValidation['default'],
                            xtype     : 'combo',
                            mode      : 'local',
                            forceSelection: true,
                            triggerAction: 'all',
                            store     : config.productNumberValidation.definition.options
                        }
                    ], [
                        {
                            fieldLabel: this.app.i18n._(config.productNumberPrefix.definition.label),
                            name      : 'productNumberPrefix',
                            value     : config.productNumberPrefix.value ? config.productNumberPrefix.value : config.productNumberPrefix['default'],
                        }, {
                            fieldLabel: this.app.i18n._(config.productNumberZeroFill.definition.label),
                            name      : 'productNumberZeroFill',
                            value     : config.productNumberZeroFill.value ? config.productNumberZeroFill.value : config.productNumberZeroFill['default'],
                            xtype     : 'uxspinner',
                            decimalPrecision: 0,
                            strategy  : new Ext.ux.form.Spinner.NumberStrategy({
                                incrementValue: 1,
                                alternateIncrementValue: 10,
                                minValue      : 0,
                                maxValue      : 100,
                                allowDecimals : 0
                            })
                        }
                    ]
                ]
            }]
        };
    } 
});

Tine.Sales.AdminPanel.openWindow = function(config) {
    var window = Tine.WindowFactory.getWindow({
        modal  : true,
        width  : 500,
        height : 250,
        contentPanelConstructor : 'Tine.Sales.AdminPanel',
        contentPanelConstructorConfig : config
    });
    return window;
};

/***/ }),

/***/ 734:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Contract selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ContractSearchCombo
 */
Tine.Sales.ContractSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Contract;
        this.recordProxy = Tine.Sales.contractBackend;

        Tine.Sales.ContractSearchCombo.superclass.initComponent.call(this);
        
        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Contract', Tine.Sales.ContractSearchCombo);


/***/ }),

/***/ 735:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Customer selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CustomerSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CustomerSearchCombo
 */
Tine.Sales.CustomerSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Customer;
        this.recordProxy = Tine.Sales.customerBackend;

        Tine.Sales.CustomerSearchCombo.superclass.initComponent.call(this);
        
        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Customer', Tine.Sales.CustomerSearchCombo);


/***/ }),

/***/ 736:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Contract selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.OfferSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2915 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.OfferSearchCombo
 */
Tine.Sales.OfferSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Offer;
        this.recordProxy = Tine.Sales.offerBackend;

        Tine.Sales.OfferSearchCombo.superclass.initComponent.call(this);
        
        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Offer', Tine.Sales.OfferSearchCombo);


/***/ }),

/***/ 737:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Contract selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.InvoiceSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.InvoiceSearchCombo
 */
Tine.Sales.InvoiceSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Invoice;
        this.recordProxy = Tine.Sales.invoiceBackend;

        Tine.Sales.InvoiceSearchCombo.superclass.initComponent.call(this);

        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Invoice', Tine.Sales.InvoiceSearchCombo);


/***/ }),

/***/ 738:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014-2015 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Supplier selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.SupplierSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014-2015 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.SupplierSearchCombo
 */
Tine.Sales.SupplierSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Supplier;
        this.recordProxy = Tine.Sales.supplierBackend;

        Tine.Sales.SupplierSearchCombo.superclass.initComponent.call(this);
        
        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Supplier', Tine.Sales.SupplierSearchCombo);


/***/ }),

/***/ 739:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * CostCenter selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CostCenterSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CostCenterSearchCombo
 */
Tine.Sales.CostCenterSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    itemSelector: 'div.search-item',
    minListWidth: 200,
    sortBy: 'number',
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.CostCenter;
        this.recordProxy = Tine.Sales.costcenterBackend;
        this.initTemplate();
        
        Tine.Sales.CostCenterSearchCombo.superclass.initComponent.call(this);
    },
    
    /**
     * init template
     * @private
     */
    initTemplate: function() {
        if (! this.tpl) {
            this.tpl = new Ext.XTemplate(
                '<tpl for="."><div class="search-item">',
                    '<table cellspacing="0" cellpadding="2" border="0" style="font-size: 11px;" width="100%">',
                        '<tr>',
                            '<td style="height:16px">{[this.encode(values)]}</td>',
                        '</tr>',
                    '</table>',
                '</div></tpl>',
                {
                    encode: function(values) {
                        var ret = '';
                        if(values.number) ret += '<b>' + Ext.util.Format.htmlEncode(values.number) + '</b> - ';
                        ret += Ext.util.Format.htmlEncode(values.remark);
                        return ret;
                        
                    }
                }
            );
        }
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'CostCenter', Tine.Sales.CostCenterSearchCombo);


/***/ }),

/***/ 740:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractCostCenterFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.ContractCostCenterFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'costcenter',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n.n_('Cost Center', 'Cost Centers', 1);
        this.foreignRecordClass = Tine.Sales.Model.CostCenter;
        this.pickerConfig = {emptyText: this.app.i18n._('without Cost Center'), allowBlank: true};

        Tine.Sales.ContractCostCenterFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.contractcostcenter'] = Tine.Sales.ContractCostCenterFilterModel;


/***/ }),

/***/ 741:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * CostCenter grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CostCenterGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>CostCenter Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stinting <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * 
 * Create a new Tine.Sales.CostCenterGridPanel
 */
Tine.Sales.CostCenterGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    // grid specific
    defaultSortInfo: {field: 'remark', dir: 'ASC'},
    gridConfig: {
        autoExpandColumn: 'remark'
    },
    
    multipleEdit: true,
    
    initComponent: function() {
        this.recordClass = Tine.Sales.Model.CostCenter;
        this.recordProxy = Tine.Sales.costcenterBackend;
        this.gridConfig.columns = this.getColumns();
        Tine.Sales.CostCenterGridPanel.superclass.initComponent.call(this);
    },
    
    /**
     * returns cm
     * @private
     */
    getColumns: function(){
        return [{
            id: 'number',
            header: this.app.i18n._("Number"),
            width: 100,
            sortable: true,
            dataIndex: 'number'
        },{
            id: 'remark',
            header: this.app.i18n._("Remark"),
            width: 200,
            sortable: true,
            dataIndex: 'remark'
        }].concat(this.getModlogColumns())
    }
});


/***/ }),

/***/ 742:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * CostCenter edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CostCenterEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>CostCenter Edit Dialog</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CostCenterGridPanel
 */
Tine.Sales.CostCenterEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    windowWidth: 650,
    windowHeight: 450,
    
    /**
     * @private
     */
    windowNamePrefix: 'CostCenterEditWindow_',
    appName: 'Sales',

    tbarItems: [],
    
    initComponent: function() {
        
        this.recordClass = Tine.Sales.Model.CostCenter;
        this.recordProxy = Tine.Sales.costcenterBackend;
        
        Tine.Sales.CostCenterEditDialog.superclass.initComponent.call(this);
    },
    /**
     * called on multiple edit
     * @return {Boolean}
     */
    isMultipleValid: function() {
        return true;
    },
    
    /**
     * @see: Tine.widgets.dialog.EditDialog.onRecordLoad
     */
    onRecordLoad: function() {
        Tine.Sales.CostCenterEditDialog.superclass.onRecordLoad.call(this);
        
        if (! this.copyRecord && ! this.record.id) {
            this.window.setTitle(this.app.i18n._('Add New Cost Center'));
        }
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            defaults: {
                hideMode: 'offsets'
            },
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Cost Center', 'Cost Centers', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: .333
                    },
                    items: [[{
                        columnWidth: .25,
                        fieldLabel: this.app.i18n._('Number'),
                        name: 'number',
                        xtype:  'numberfield',
                        multiEditable: false,
                        allowBlank: false
                    },{
                        columnWidth: .75,
                        fieldLabel: this.app.i18n._('Remark'),
                        name: 'remark',
                        allowBlank: false
                    }]
                    ]
                }]
            }]
        };
    }
});

/**
 * Sales Edit Popup
 */
Tine.Sales.CostCenterEditDialog.openWindow = function (config) {
    var id = (config.record && config.record.id) ? config.record.id : 0;
    var window = Tine.WindowFactory.getWindow({
        width: 650,
        height: 450,
        name: Tine.Sales.CostCenterEditDialog.prototype.windowNamePrefix + id,
        contentPanelConstructor: 'Tine.Sales.CostCenterEditDialog',
        contentPanelConstructorConfig: config
    });
    return window;
};


/***/ }),

/***/ 743:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractContactInternalFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.ContractContactInternalFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'costcenter',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Contact Person (internal)');
        this.foreignRecordClass = Tine.Addressbook.Model.Contact;
        this.pickerConfig = {emptyText: this.app.i18n._('without internal contact person'), allowBlank: true};

        Tine.Sales.ContractContactInternalFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.contract-contact-internal'] = Tine.Sales.ContractContactInternalFilterModel;


/***/ }),

/***/ 744:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractContactExternalFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.ContractContactExternalFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'costcenter',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Contact Person (external)');
        this.foreignRecordClass = Tine.Addressbook.Model.Contact;
        this.pickerConfig = {emptyText: this.app.i18n._('without external contact person'), allowBlank: true};

        Tine.Sales.ContractContactExternalFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.contract-contact-external'] = Tine.Sales.ContractContactExternalFilterModel;


/***/ }),

/***/ 745:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractProductFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Philipp Schüle <p.schuele@metaways.de>
 */
Tine.Sales.ContractProductFilterModel = Ext.extend(Tine.widgets.grid.FilterModel, {
    
    // private
    field: 'products',
    operators: ['contains'],
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Products');
        //this.pickerConfig = {emptyText: this.app.i18n._('without customer'), allowBlank: true};

        Tine.Sales.ContractProductFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.contract-product'] = Tine.Sales.ContractProductFilterModel;


/***/ }),

/***/ 746:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Contract grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Contract Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ContractGridPanel
 */
Tine.Sales.ContractGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    multipleEdit: true,
    initComponent: function() {
        Tine.Sales.ContractGridPanel.superclass.initComponent.call(this);
        this.action_addInNewWindow.actionUpdater = function() {
            var defaultContainer = this.app.getRegistry().get('defaultContainer');
            this.action_addInNewWindow.setDisabled(! defaultContainer.account_grants[this.action_addInNewWindow.initialConfig.requiredGrant]);
        }
    },
    
    /**
     * @todo: make this generally available (here its more general: Tine.HumanResources.EmployeeGridPanel)
     * 
     * returns additional toobar items
     * 
     * @return {Array} of Ext.Action
     */
    getActionToolbarItems: function() {
        this.actions_bill = new Ext.Action({
            text: this.app.i18n._('Bill Contract'),
            iconCls: 'action_bill',
            scope: this,
            disabled: true,
            allowMultiple: false,
            handler: this.onBillContract,
            actionUpdater: function(action, grants, records) {
                if (records.length == 1) {
                    action.enable();
                } else {
                    action.disable();
                }
            }
        });

        var billButton = Ext.apply(new Ext.Button(this.actions_bill), {
            scale: 'medium',
            rowspan: 2,
            iconAlign: 'top'
        });
        
        var additionalActions = [this.actions_bill];
        this.actionUpdater.addActions(additionalActions);
        
        return [billButton];
    },
    
    /**
     * is called when the component is rendered
     * @param {} ct
     * @param {} position
     */
    onRender : function(ct, position) {
        this.billMask = new Ext.LoadMask(ct, {msg: this.app.i18n._('Billing Contract...')});
        Tine.Sales.ContractGridPanel.superclass.onRender.call(this, ct, position);
    },
    
    /**
     * 
     */
    onBillContract: function() {
        var rows = this.getGrid().getSelectionModel().getSelections();
        
        if (rows.length != 1) {
            return;
        }
        
        var window = Tine.Sales.BillingDateDialog.openWindow({
            winTitle: String.format(this.app.i18n._('Bill Contract "{0} - {1}"'), rows[0].data.number, rows[0].data.title),
            panelDialog: this.app.i18n._('Select the date to generate the bill for'),
            contractId: rows[0].id
        });
        
        window.on('submit', this.doBillContract, this);
    },
    
    /**
     * 
     * @param {} date
     * @param {} contractId
     */
    doBillContract: function(date, contractId) {
        var that = this;
        
        this.billMask.show();
        
        var req = Ext.Ajax.request({
            url : 'index.php',
            params : { 
                method: 'Sales.billContract', 
                id:     contractId,
                date:   date
            },
            success : function(result, request) {
                that.getGrid().store.reload();
                that.billMask.hide();
            },
            failure : function(exception) {
                that.billMask.hide();
                Tine.Tinebase.ExceptionHandler.handleRequestException(exception);
            },
            scope: that
        });
    },
    
    /**
     * add custom items to context menu
     * 
     * @return {Array}
     */
    getContextMenuItems: function() {
        var items = [
            '-',
            this.actions_bill
            ];
        
        return items;
    }
});


/***/ }),

/***/ 747:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2010 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Contract edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Contract Edit Dialog</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ContractGridPanel
 */
Tine.Sales.ContractEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    windowWidth: 800,
    windowHeight: 600,
    displayNotes: true,

    /**
     * autoset
     * 
     * @type combo
     */
    customerPicker: null,
    
    /**
     * autoset
     * 
     * @type combo
     */
    addressPicker: null,
    
    /**
     * if true, number will be readOnly and will be generated automatically
     * @type {Boolean} autoGenerateNumber
     */
    autoGenerateNumber: null,
    
    /**
     * how should the number be validated text/integer possible
     * @type {String} validateNumber
     */
    validateNumber: null,

    displayNotes: true,
    
    initComponent: function() {
        this.autoGenerateNumber = (Tine.Sales.registry.get('config').contractNumberGeneration.value == 'auto') ? true : false;
        this.validateNumber = Tine.Sales.registry.get('config').contractNumberValidation.value;

        Tine.Sales.ContractEditDialog.superclass.initComponent.call(this);
    },
    
    /**
     * called on multiple edit
     *
     * @return {Boolean}
     */
    isMultipleValid: function() {
        return true;
    },
    
    /**
     * containerProperty (all contracts in one container) exists, so overwrite creating selector here
     */
    initContainerSelector: Ext.emptyFn,
    
    /**
     * extra validation for the number field, calls parent
     * @return {Boolean}
     */
    isValid: function() {
        var valid = Tine.Sales.ContractEditDialog.superclass.isValid.call(this);
        var isValid = this.autoGenerateNumber ? true : (this.validateNumber == 'integer') ? Ext.isNumber(Ext.num(this.getForm().findField('number').getValue())) : true;
        if (!isValid) {
            this.getForm().findField('number').markInvalid(this.app.i18n._('Please use a decimal number here!'));
        }
        return isValid && valid;
    },
    
    /**
     * executed after record got updated from proxy
     * 
     * @private
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        Tine.Sales.ContractEditDialog.superclass.onRecordLoad.call(this);
        
        if (this.record.id) {
            var relations = this.record.get('relations'), foundCustomer = false;
            
            if (Ext.isArray(relations)) {
                for (var index = 0; index < relations.length; index++) {
                    if (relations[index].related_model == 'Sales_Model_Customer') {
                        if (relations[index].type == 'CUSTOMER') {
                            foundCustomer = relations[index].related_record;
                        }
                    }
                }
            }
            
            if (foundCustomer) {
                this.addressPicker.enable();
                var ba = this.record.get('billing_address_id');
                
                if (ba && ba.hasOwnProperty('locality')) {
                    var record = new Tine.Sales.Model.Address(ba);
                }
             
                this.setAddressPickerFilter();
            }
        }
    },
    
    /**
     * sets the filter used for the addresspicker by the selected customer
     */
    setAddressPickerFilter: function() {
        this.addressPicker.additionalFilters = [
            {field: 'type', operator: 'not', value: 'delivery'},
            {field: 'customer_id', operator: 'AND', value: [
                {field: ':id', operator: 'in', value: [this.customerPicker.getValue()] }
            ]}
        ];
    },
    
    /**
     * loads the full-featured record, if a contract gets selected
     * 
     * @param {Tine.widgets.relation.PickerCombo} combo
     * @param {Tine.Sales.Model.Contract} record
     * @param {Number} index
     */
    onCustomerLoad: function(combo, record, index) {
        if (this.addressPicker.disabled) {
            this.addressPicker.enable();
        } else {
            this.addressPicker.reset();
        }
        
        this.addressPicker.lastQuery = null;
        this.setAddressPickerFilter();
        this.loadAddress(record);
    },
    
    /**
     * loads the first billing address or the postal 
     * address into the addresspicker on loading a customer
     * 
     * @param {Tine.Sales.Model.Customer} record
     */
    loadAddress: function(record) {
        var billingAddresses = record.get('billing');
        if (Ext.isArray(billingAddresses) && billingAddresses.length > 0) {
            var address = new Tine.Sales.Model.Address(billingAddresses[0]);
        } else {
            var address = new Tine.Sales.Model.Address(record.get('postal_id'));
        }
        
        this.addressPicker.setValue(address.data);
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        
        this.productGridPanel = new Tine.Sales.ProductAggregateGridPanel({
            app: this.app,
            editDialog: this,
            title: this.app.i18n._('Products'),
            editDialogRecordProperty: 'products'
        });
        
        var items = [[{
            columnWidth: .25,
            fieldLabel: this.app.i18n._('Number'),
            name: 'number',
            multiEditable: false,
            readOnly: this.autoGenerateNumber,
            allowBlank: this.autoGenerateNumber
        },{
            columnWidth: .75,
            fieldLabel: this.app.i18n._('Title'),
            name: 'title',
            allowBlank: false
        }], [{
            columnWidth: 1,
            editDialog: this,
            xtype: 'tinerelationpickercombo',
            allowBlank: true,
            app: 'Sales',
            recordClass: Tine.Sales.Model.Customer,
            relationType: 'CUSTOMER',
            relationDegree: 'sibling',
            modelUnique: true,
            listeners: {
                scope: this,
                select: this.onCustomerLoad
            },
            ref: '../../../../../customerPicker',
            fieldLabel: this.app.i18n._('Customer')
        }], [ Tine.widgets.form.RecordPickerManager.get('Sales', 'Address', {
                fieldLabel: this.app.i18n._('Billing Address'),
                name: 'billing_address_id',
                ref: '../../../../../addressPicker',
                columnWidth: 1,
                disabled: true,
                allowBlank: true
            })], [{
                    xtype: 'extuxclearabledatefield',
                    name: 'start_date',
                    columnWidth: 1/2,
                    fieldLabel: this.app.i18n._('Start Date'),
                    allowBlank: false
                }, {
                    xtype: 'extuxclearabledatefield',
                    name: 'end_date',
                    fieldLabel: this.app.i18n._('End Date'),
                    columnWidth: 1/2
                }], [{
                columnWidth: 1/3,
                xtype: 'tinerelationpickercombo',
                fieldLabel: this.app.i18n._('Contact Person (external)'),
                editDialog: this,
                allowBlank: true,
                app: 'Addressbook',
                recordClass: Tine.Addressbook.Model.Contact,
                relationType: 'CUSTOMER',
                relationDegree: 'sibling',
                modelUnique: true
            }, {
                columnWidth: 1/3,
                editDialog: this,
                xtype: 'tinerelationpickercombo',
                fieldLabel: this.app.i18n._('Contact Person (internal)'),
                allowBlank: true,
                app: 'Addressbook',
                recordClass: Tine.Addressbook.Model.Contact,
                relationType: 'RESPONSIBLE',
                relationDegree: 'sibling',
                modelUnique: true
            }, {
                columnWidth: 1/3,
                editDialog: this,
                xtype: 'tinerelationpickercombo',
                fieldLabel: this.app.i18n._('Lead Cost Center'),
                allowBlank: true,
                app: 'Sales',
                recordClass: Tine.Sales.Model.CostCenter,
                relationType: 'LEAD_COST_CENTER',
                relationDegree: 'sibling',
                modelUnique: true
            }]];
            
        items.push([{
            columnWidth: 1,
            fieldLabel: this.app.i18n._('Description'),
            emptyText: this.app.i18n._('Enter description...'),
            name: 'description',
            xtype: 'textarea',
            height: 200
        }]);
        
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            defaults: {
                hideMode: 'offsets'
            },
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Contract', 'Contracts', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: .333
                    },
                    items: items
                }, {
                    // activities and tags
                    layout: 'ux.multiaccordion',
                    animate: true,
                    region: 'east',
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                        new Tine.widgets.tags.TagPanel({
                            app: 'Sales',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            }, this.productGridPanel,
                new Tine.widgets.activities.ActivitiesTabPanel({
                    app: this.appName,
                    record_id: this.record.id,
                    record_model: 'Sales_Model_Contract'
                })
            ]
        };
    }
});


/***/ }),

/***/ 748:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schüle <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2009-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Product grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ProductGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Product Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ProductGridPanel
 */
Tine.Sales.ProductGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    /**
     * inits this cmp
     * @private
     */
    initComponent: function() {
        Tine.Sales.ProductGridPanel.superclass.initComponent.call(this);
        
        // actions depend on manage_products right
        this.selectionModel.on('selectionchange', function(sm) {
            var hasManageRight = Tine.Tinebase.common.hasRight('manage', 'Sales', 'products');

            if (hasManageRight) {
                Tine.widgets.actionUpdater(sm, this.actions, this.recordClass.getMeta('containerProperty'), !this.evalGrants);
                if (this.updateOnSelectionChange && this.detailsPanel) {
                    this.detailsPanel.onDetailsUpdate(sm);
                }
            } else {
                this.action_editInNewWindow.setDisabled(true);
                this.action_deleteRecord.setDisabled(true);
                this.action_tagsMassAttach.setDisabled(true);
            }
        }, this);

        this.action_addInNewWindow.setDisabled(! Tine.Tinebase.common.hasRight('manage', 'Sales', 'products'));
    }
});


/***/ }),

/***/ 749:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2009 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Product edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ProductEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Product Edit Dialog</p>
 * <p><pre>
 * TODO         make category a combobox + get data from settings
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Philipp Schuele <p.schuele@metaways.de>
 * @copyright   Copyright (c) 2009 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ProductGridPanel
 */
Tine.Sales.ProductEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    windowWidth: 800,
    windowHeight: 600,
    displayNotes: true,
    
    onRecordLoad: function() {
        Tine.Sales.ProductEditDialog.superclass.onRecordLoad.call(this);
        
        if (! this.copyRecord && ! this.record.id) {
            this.window.setTitle(this.app.i18n._('Add New Product'));
        }
    },
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Product', 'Products', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: 1/3
                    },
                    items: [[{
                        name: 'number',
                        fieldLabel: this.app.i18n._('Product Number'),
                        columnWidth: 1/3
                    }, {
                        name: 'gtin',
                        fieldLabel: this.app.i18n._('GTIN'),
                        columnWidth: 1/3
                    }, new Tine.Tinebase.widgets.keyfield.ComboBox({
                        app: 'Sales',
                        keyFieldName: 'productCategory',
                        fieldLabel: this.app.i18n._('Category'),
                        name: 'category',
                        columnWidth: 1/3
                    })], [{
                        columnWidth: 1,
                        fieldLabel: this.app.i18n._('Name'),
                        name: 'name',
                        allowBlank: false
                    }], [{
                        columnWidth: 1,
                        fieldLabel: this.app.i18n._('Manufacturer'),
                        name: 'manufacturer'
                    }], [{
                        xtype: 'extuxmoneyfield',
                        fieldLabel: this.app.i18n._('Purchaseprice'),
                        name: 'purchaseprice',
                        allowNegative: false,
                        allowBlank: true
                    }, {
                        xtype: 'extuxmoneyfield',
                        fieldLabel: this.app.i18n._('Salesprice'),
                        name: 'salesprice',
                        allowNegative: false,
                        allowBlank: true
                    }, this.getAccountableCombo()],
                    [{
                        columnWidth: 0.5,
                        name: 'lifespan_start',
                        xtype: 'datefield',
                        fieldLabel: this.app.i18n._('Lifespan start')
                    }, {
                        columnWidth: 0.5,
                        xtype: 'datefield',
                        name: 'lifespan_end',
                        fieldLabel: this.app.i18n._('Lifespan end')
                    }], [{
                        columnWidth: 1,
                        fieldLabel: this.app.i18n._('Description'),
                        emptyText: this.app.i18n._('Enter description...'),
                        name: 'description',
                        xtype: 'textarea',
                        height: 150
                    }]]
                }, {
                    // activities and tags
                    layout: 'ux.multiaccordion',
                    animate: true,
                    region: 'east',
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                        new Tine.widgets.tags.TagPanel({
                            app: 'Sales',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            },
            new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: this.appName + '_Model_' + this.recordClass.getMeta('modelName')
            })
            ]
        };
    },
    
    /**
     * creates the accountable combo box
     * 
     * @return {Ext.form.ComboBox}
     */
    getAccountableCombo: function() {
        if (! this.accountableCombo) {
            var data = [];
            var id = 0;

            Ext.each(Tine.Sales.AccountableRegistry.getArray(), function(rel) {
                
                var app = Tine.Tinebase.appMgr.get(rel.appName);
                var tr = app.i18n._(rel.appName + rel.modelName);
                
                data.push([rel.appName + '_Model_' + rel.modelName, tr]);
                id++;
            });

            this.accountableCombo = new Ext.ux.form.ClearableComboBox({
                store: new Ext.data.ArrayStore({
                    fields: ['key', 'modelName'],
                    data: data
                }),
                fieldLabel: this.app.i18n._('Accountable'),
                allowBlank: false,
                forceSelection: true,
                value: 'Sales_Model_Product',
                displayField: 'modelName',
                valueField: 'key',
                name: 'accountable',
                columnWidth: 1/3,
                mode: 'local'
            });

        }
        return this.accountableCombo;
    }
});


/***/ }),

/***/ 750:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CustomerEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Customer Compose Dialog</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CustomerEditDialog
 */
Tine.Sales.CustomerEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    windowWidth: 900,
    windowHeight: 800,
    displayNotes: true,
    
    initComponent: function() {
        Tine.Sales.CustomerEditDialog.superclass.initComponent.call(this);
    },
    
    /**
     * 
     */
    isValid: function() {
        var isValid = true,
            form = this.getForm();
        
        isValid = Tine.Sales.CustomerEditDialog.superclass.isValid.call(this)

        if (Ext.isEmpty(form.findField('adr_street').getValue()) && Ext.isEmpty(form.findField('adr_pobox').getValue())) {
            isValid = false;
            var msg = this.app.i18n._('Either street or postbox is required!');
            form.markInvalid( {'adr_street': msg, 'adr_pobox': msg});
        }

        var number = form.findField('number').getValue();
        if (number.match(/[^0-9^]+/)) {
            isValid = false;
            form.markInvalid( {'number': this.app.i18n._('Only numbers are allowed!')});
        }

        return isValid;
    },
    
    /**
     * executed after record got updated from proxy
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        Tine.Sales.CustomerEditDialog.superclass.onRecordLoad.call(this);
        
        if (this.copyRecord) {
            this.doCopyRecord();
            this.window.setTitle(this.app.i18n._('Copy Customer'));
        } else {
            if (! this.record.id) {
                this.window.setTitle(this.app.i18n._('Add New Customer'));
            } else {
                this.window.setTitle(String.format(this.app.i18n._('Edit Customer "{0}"'), this.record.getTitle()));
                this.getForm().findField('number').disable();
            }
        }
    },
    
    /**
     * duplicate(s) found exception handler
     * 
     * @todo: make this globally, smoothly the virtual fields (modelconfig) don't fit anywhere
     * 
     * @param {Object} exception
     */
    onDuplicateException: function(exception) {
        this.onRecordUpdate();
        exception.clientRecord = this.record.data;
        Tine.Sales.CustomerEditDialog.superclass.onDuplicateException.call(this, exception);
    },
    
    /**
     * Fill address with contact data, if not set already
     * 
     * @param {} combo
     * @param {} record
     * @param {} index
     */
    onSelectContactPerson: function(combo, record, index) {
        var form = this.getForm();
        if (record.get('adr_one_street') && ! form.findField('adr_street').getValue()) {
            var ar = ['street', 'postalcode', 'region', 'locality', 'countryname'];
            for (var index = 0; index < ar.length; index++) {
                form.findField('adr_' + ar[index]).setValue(record.get('adr_one_' + ar[index]));
            }
        }
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     * 
     * @return {Object}
     * @private
     */
    getFormItems: function() {
        var formFieldDefaults = {
            xtype:'textfield',
            anchor: '100%',
            labelSeparator: '',
            columnWidth: .5
        };
        
        this.clipboardButton = new Ext.Button({
           columnWidth: 5/100,
           iconCls: 'clipboard',
           tooltip: Ext.util.Format.htmlEncode(this.app.i18n._('Copy address to the clipboard')),
           fieldLabel: '&nbsp;',
           lazyLoading: false,
           listeners: {
                scope: this,
                click: function() {
                    this.onRecordUpdate();
                    Tine.Sales.addToClipboard(this.record);
                }
           }
        });
        
        var currency = Tine.Sales.registry.get('config').ownCurrency.value;
        
        this.billingAddressGridPanel = new Tine.Sales.BillingAddressGridPanel({
            app: this.app,
            editDialog: this,
            frame: false,
            border: true,
            autoScroll: true,
            layout: 'border',
            editDialogRecordProperty: 'billing'
        });
        
        this.deliveryAddressGridPanel = new Tine.Sales.DeliveryAddressGridPanel({
            app: this.app,
            editDialog: this,
            frame: false,
            border: true,
            autoScroll: true,
            layout: 'border',
            editDialogRecordProperty: 'delivery'
        });
        
        return {
            xtype: 'tabpanel',
            defaults: {
                hideMode: 'offsets'
            },
            border: false,
            plain: true,
            activeTab: 0,
            items: [{
            title: this.app.i18n._('Customer'),
            autoScroll: true,
            border: false,
            frame: true,
            layout: 'border',
            items: [{
                region: 'center',
                layout: 'hfit',
                border: false,
                items: [{
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Core Data'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [[{
                                fieldLabel: this.app.i18n._('Customer Number'),
                                name: 'number',
                                allowBlank: true,
                                columnWidth: .250,
                                minValue: 1,
                                maxValue: 4294967296,
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 1,
                                    alternateIncrementValue: 1,
                                    minValue: 1,
                                    maxValue: 4294967296,
                                    allowDecimals : false
                                })
                            }, {
                                columnWidth: .750,
                                allowBlank: false,
                                fieldLabel: this.app.i18n._('Name'),
                                name: 'name',
                                xtype: 'tine.widget.field.AutoCompleteField',
                                recordClass: this.recordClass
                            }], [Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                    columnWidth: 1/2,
                                    blurOnSelect: true,
                                    name: 'cpextern_id',
                                    allowBlank: true,
                                    fieldLabel: this.app.i18n._('Contact Person (external)'),
                                    listeners: {
                                        scope: this,
                                        select: this.onSelectContactPerson
                                    }
                            }), Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                    columnWidth: 1/2,
                                    blurOnSelect: true,
                                    name: 'cpintern_id',
                                    allowBlank: true,
                                    fieldLabel: this.app.i18n._('Contact Person (internal)')
                                })
                        ]]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Accounting'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                name: 'vatid',
                                fieldLabel: this.app.i18n._('VAT No.')
                            }, {
                                name: 'credit_term',
                                fieldLabel: this.app.i18n._('Credit Term (days)'),
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 1,
                                    alternateIncrementValue: 1,
                                    minValue: 0,
                                    maxValue: 1024,
                                    allowDecimals : false
                                })
                            }], [{
                                name: 'currency',
                                fieldLabel: this.app.i18n._('Currency'),
                                value: currency,
                                allowBlank: false
                            }, {
                                name: 'currency_trans_rate',
                                fieldLabel: this.app.i18n._('Currency Translation Rate'),
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 0.01,
                                    alternateIncrementValue: 0.1,
                                    minValue: 0.01,
                                    allowDecimals : true
                                }),
                                decimalPrecision: 2,
                                decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
                                regex: /^[0-9]+\.?[0-9]*$/
                            }], [{
                                name: 'iban',
                                fieldLabel: this.app.i18n._('IBAN')
                            }, {
                                name: 'bic',
                                fieldLabel: this.app.i18n._('BIC')
                            }], [{
                                name: 'discount',
                                fieldLabel: this.app.i18n._('Discount (%)'),
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 0.1,
                                    alternateIncrementValue: 1,
                                    minValue: 0,
                                    maxValue: 100,
                                    allowDecimals : true
                                }),
                                decimalPrecision: 1,
                                decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator')
                            }, {
                                name: 'name_shorthand',
                                fieldLabel: this.app.i18n._('Name shorthand')
                            }
                        ]]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Postal Address'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                name: 'adr_street',
                                fieldLabel: this.app.i18n._('Street'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_pobox',
                                fieldLabel: this.app.i18n._('Postbox'),
                                columnWidth: 47/100
                                
                            }], [{
                                name: 'adr_postalcode',
                                allowBlank: false,
                                fieldLabel: this.app.i18n._('Postalcode'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_locality',
                                allowBlank: false,
                                fieldLabel: this.app.i18n._('Locality'),
                                columnWidth: 47/100
                            }], [{
                                name: 'adr_region',
                                fieldLabel: this.app.i18n._('Region'),
                                columnWidth: 47/100
                            }, {
                                xtype: 'widget-countrycombo',
                                name: 'adr_countryname',
                                fieldLabel: this.app.i18n._('Country'),
                                columnWidth: 47/100
                            }
                            ], [{
                                name: 'adr_prefix1',
                                fieldLabel: this.app.i18n._('Prefix'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_prefix2',
                                fieldLabel: this.app.i18n._('Additional Prefix'),
                                columnWidth: 48/100
                            }, this.clipboardButton]
                        ]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Miscellaneous'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [[
                            {
                                columnWidth: 1/3,
                                fieldLabel: this.app.i18n._('Web'),
                                xtype: 'mirrortextfield',
                                name: 'url',
                                maxLength: 128,
                                listeners: {
                                    scope: this,
                                    focus: function (field) {
                                        if (! field.getValue()) {
                                            field.setValue('http://www.');
                                            field.selectText.defer(100, field, [7, 11]);
                                        }
                                    },
                                    blur: function (field) {
                                        if (field.getValue() === 'http://www.') {
                                            field.setValue(null);
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://http://') == 0 || field.getValue().indexOf('http://https://') == 0) {
                                            field.setValue(field.getValue().substr(7));
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://www.http://') == 0 || field.getValue().indexOf('http://www.https://') == 0) {
                                            field.setValue(field.getValue().substr(11));
                                            field.validate();
                                        }
                                    }
                                }
                            }
                        ]]
                    }]
                }]
            }, {
                // activities and tags
                layout: 'ux.multiaccordion',
                animate: true,
                region: 'east',
                width: 210,
                split: true,
                collapsible: true,
                collapseMode: 'mini',
                header: false,
                margins: '0 5 0 5',
                border: true,
                items: [
                    new Ext.Panel({
                        title: this.app.i18n._('Description'),
                        iconCls: 'descriptionIcon',
                        layout: 'form',
                        labelAlign: 'top',
                        border: false,
                        items: [{
                            style: 'margin-top: -4px; border 0px;',
                            labelSeparator: '',
                            xtype: 'textarea',
                            name: 'description',
                            hideLabel: true,
                            grow: false,
                            preventScrollbars: false,
                            anchor: '100% 100%',
                            emptyText: this.app.i18n._('Enter description'),
                            requiredGrant: 'editGrant'
                        }]
                    }),
                    new Tine.widgets.tags.TagPanel({
                        app: 'Sales',
                        border: false,
                        bodyStyle: 'border:1px solid #B5B8C8;'
                    })
                ]
            }]
        }, this.billingAddressGridPanel,
           this.deliveryAddressGridPanel,
           new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: 'Sales_Model_Customer'
            })
        ]};
    }
});


/***/ }),

/***/ 751:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.SupplierEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Supplier Compose Dialog</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.SupplierEditDialog
 */
Tine.Sales.SupplierEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    windowWidth: 900,
    windowHeight: 800,
    displayNotes: true,
    
    /**
     * 
     */
    isValid: function() {
        var isValid = true,
            form = this.getForm();
        
        isValid = Tine.Sales.SupplierEditDialog.superclass.isValid.call(this)
            
        if (Ext.isEmpty(form.findField('adr_postalcode').getValue()) && Ext.isEmpty(form.findField('adr_pobox').getValue())) {
            isValid = false;
            var msg = this.app.i18n._('Either postalcode or postbox is required!');
            form.markInvalid( {'adr_postalcode': msg, 'adr_pobox': msg});
        }

        return isValid;
    },
    
    /**
     * executed after record got updated from proxy
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        Tine.Sales.SupplierEditDialog.superclass.onRecordLoad.call(this);
        
        if (this.copyRecord) {
            this.doCopyRecord();
            this.window.setTitle(this.app.i18n._('Copy Supplier'));
        } else {
            if (! this.record.id) {
                this.window.setTitle(this.app.i18n._('Add New Supplier'));
            } else {
                this.window.setTitle(String.format(this.app.i18n._('Edit Supplier "{0}"'), this.record.getTitle()));
                //this.getForm().findField('number').disable();
            }
        }
    },
    
    /**
     * duplicate(s) found exception handler
     * 
     * @todo: make this globally, smoothly the virtual fields (modelconfig) don't fit anywhere
     * 
     * @param {Object} exception
     */
    onDuplicateException: function(exception) {
        this.onRecordUpdate();
        exception.clientRecord = this.record.data;
        Tine.Sales.SupplierEditDialog.superclass.onDuplicateException.call(this, exception);
    },
    
    /**
     * Fill address with contact data, if not set already
     * 
     * @param {} combo
     * @param {} record
     * @param {} index
     */
    onSelectContactPerson: function(combo, record, index) {
        var form = this.getForm();
        if (record.get('adr_one_street') && ! form.findField('adr_street').getValue()) {
            var ar = ['street', 'postalcode', 'region', 'locality', 'countryname'];
            for (var index = 0; index < ar.length; index++) {
                form.findField('adr_' + ar[index]).setValue(record.get('adr_one_' + ar[index]));
            }
        }
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     * 
     * @return {Object}
     * @private
     */
    getFormItems: function() {
        var formFieldDefaults = {
            xtype:'textfield',
            anchor: '100%',
            labelSeparator: '',
            columnWidth: .5
        };
        
        this.clipboardButton = new Ext.Button({
           columnWidth: 5/100,
           iconCls: 'clipboard',
           tooltip: Ext.util.Format.htmlEncode(this.app.i18n._('Copy address to the clipboard')),
           fieldLabel: '&nbsp;',
           lazyLoading: false,
           listeners: {
                scope: this,
                click: function() {
                    this.onRecordUpdate();
                    Tine.Sales.addToClipboard(this.record);
                }
           }
        });
        
        var currency = Tine.Sales.registry.get('config').ownCurrency.value;
        
        return {
            xtype: 'tabpanel',
            defaults: {
                hideMode: 'offsets'
            },
            border: false,
            plain: true,
            activeTab: 0,
            items: [{
            title: this.app.i18n._('Supplier'),
            autoScroll: true,
            border: false,
            frame: true,
            layout: 'border',
            items: [{
                region: 'center',
                layout: 'hfit',
                border: false,
                items: [{
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Core Data'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [[{
                                fieldLabel: this.app.i18n._('Supplier Number'),
                                name: 'number',
                                allowBlank: true,
                                columnWidth: .250,
                                minValue: 1,
                                maxValue: 4294967296,
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 1,
                                    alternateIncrementValue: 1,
                                    minValue: 1,
                                    maxValue: 4294967296,
                                    allowDecimals : false
                                })
                            }, {
                                columnWidth: .750,
                                allowBlank: false,
                                fieldLabel: this.app.i18n._('Name'),
                                name: 'name',
                                xtype: 'tine.widget.field.AutoCompleteField',
                                recordClass: this.recordClass
                            }], [Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                    columnWidth: 1/2,
                                    blurOnSelect: true,
                                    name: 'cpextern_id',
                                    allowBlank: true,
                                    fieldLabel: this.app.i18n._('Contact Person (external)'),
                                    listeners: {
                                        scope: this,
                                        select: this.onSelectContactPerson
                                    }
                            }), Tine.widgets.form.RecordPickerManager.get('Addressbook', 'Contact', {
                                    columnWidth: 1/2,
                                    blurOnSelect: true,
                                    name: 'cpintern_id',
                                    allowBlank: true,
                                    fieldLabel: this.app.i18n._('Contact Person (internal)')
                                })
                        ]]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Accounting'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                name: 'vatid',
                                fieldLabel: this.app.i18n._('VAT No.')
                            }, {
                                name: 'credit_term',
                                fieldLabel: this.app.i18n._('Credit Term (days)'),
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 1,
                                    alternateIncrementValue: 1,
                                    minValue: 0,
                                    maxValue: 1024,
                                    allowDecimals : false
                                })
                            }], [{
                                name: 'currency',
                                fieldLabel: this.app.i18n._('Currency'),
                                value: currency,
                                allowBlank: false
                            }, {
                                name: 'currency_trans_rate',
                                fieldLabel: this.app.i18n._('Currency Translation Rate'),
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 0.01,
                                    alternateIncrementValue: 0.1,
                                    minValue: 0.01,
                                    allowDecimals : true
                                }),
                                decimalPrecision: 2,
                                decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
                                regex: /^[0-9]+\.?[0-9]*$/
                            }], [{
                                name: 'iban',
                                fieldLabel: this.app.i18n._('IBAN')
                            }, {
                                name: 'bic',
                                fieldLabel: this.app.i18n._('BIC')
                            }]]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Postal Address'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                name: 'adr_street',
                                fieldLabel: this.app.i18n._('Street'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_pobox',
                                fieldLabel: this.app.i18n._('Postbox'),
                                columnWidth: 47/100
                                
                            }], [{
                                name: 'adr_postalcode',
                                allowBlank: false,
                                fieldLabel: this.app.i18n._('Postalcode'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_locality',
                                allowBlank: true,
                                fieldLabel: this.app.i18n._('Locality'),
                                columnWidth: 47/100
                            }], [{
                                name: 'adr_region',
                                fieldLabel: this.app.i18n._('Region'),
                                columnWidth: 47/100
                            }, {
                                xtype: 'widget-countrycombo',
                                name: 'adr_countryname',
                                fieldLabel: this.app.i18n._('Country'),
                                columnWidth: 47/100
                            }
                            ], [{
                                name: 'adr_prefix1',
                                fieldLabel: this.app.i18n._('Prefix'),
                                columnWidth: 47/100
                            }, {
                                name: 'adr_prefix2',
                                fieldLabel: this.app.i18n._('Additional Prefix'),
                                columnWidth: 48/100
                            }, this.clipboardButton]
                        ]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Miscellaneous'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [[
                            {
                                columnWidth: 1/3,
                                fieldLabel: this.app.i18n._('Web'),
                                xtype: 'mirrortextfield',
                                name: 'url',
                                maxLength: 128,
                                listeners: {
                                    scope: this,
                                    focus: function (field) {
                                        if (! field.getValue()) {
                                            field.setValue('http://www.');
                                            field.selectText.defer(100, field, [7, 11]);
                                        }
                                    },
                                    blur: function (field) {
                                        if (field.getValue() === 'http://www.') {
                                            field.setValue(null);
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://http://') == 0 || field.getValue().indexOf('http://https://') == 0) {
                                            field.setValue(field.getValue().substr(7));
                                            field.validate();
                                        }
                                        if (field.getValue().indexOf('http://www.http://') == 0 || field.getValue().indexOf('http://www.https://') == 0) {
                                            field.setValue(field.getValue().substr(11));
                                            field.validate();
                                        }
                                    }
                                }
                            }
                        ]]
                    }]
                }]
            }, {
                // activities and tags
                layout: 'ux.multiaccordion',
                animate: true,
                region: 'east',
                width: 210,
                split: true,
                collapsible: true,
                collapseMode: 'mini',
                header: false,
                margins: '0 5 0 5',
                border: true,
                items: [
                    new Ext.Panel({
                        title: this.app.i18n._('Description'),
                        iconCls: 'descriptionIcon',
                        layout: 'form',
                        labelAlign: 'top',
                        border: false,
                        items: [{
                            style: 'margin-top: -4px; border 0px;',
                            labelSeparator: '',
                            xtype: 'textarea',
                            name: 'description',
                            hideLabel: true,
                            grow: false,
                            preventScrollbars: false,
                            anchor: '100% 100%',
                            emptyText: this.app.i18n._('Enter description'),
                            requiredGrant: 'editGrant'
                        }]
                    }),
                    new Tine.widgets.tags.TagPanel({
                        app: 'Sales',
                        border: false,
                        bodyStyle: 'border:1px solid #B5B8C8;'
                    })
                ]
            }]
        },
           new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: 'Sales_Model_Supplier'
            })
        ]};
    }
});


/***/ }),

/***/ 752:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2015 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Address grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.AddressGridPanel
 * @extends     Tine.widgets.grid.BbarGridPanel
 * 
 * <p>Address Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.AddressGridPanel
 */
Tine.Sales.AddressGridPanel = Ext.extend(Tine.widgets.grid.BbarGridPanel, {
    
    /**
     * holds the type of the address currently handled, autoset by editDialog
     * 
     * @type {String}
     */
    addressType: null,

    defaultSortInfo: {field: 'countryname', direction: 'ASC'},
    
    /**
     * inits this cmp
     * 
     * @private
     */
    initComponent: function() {
        this.clipboardAction = new Ext.ux.grid.ActionColumnPlugin({
            header: this.app.i18n._('Clipboard'),
            keepSelection: false,
            actions: [{
                iconIndex: 'copy_clipboard',
                iconCls: 'clipboard',
                tooltip: this.app.i18n._('Copy address to the clipboard'),
                callback: this.onCopyToClipboard,
                name: 'clipboard'
            }]
        });
        
        this.plugins = Ext.isArray(this.plugins) ? this.plugins.push(this.clipboardAction) : [this.clipboardAction];
        
        Tine.Sales.AddressGridPanel.superclass.initComponent.call(this);
    },

    /**
     * returns canonical path part
     * @returns {string}
     */
    getCanonicalPathSegment: function () {
        var pathSegment = '';
        if (this.canonicalName) {
            // simple segment e.g. when used in a dialog
            pathSegment = this.canonicalName;
        } else if (this.recordClass) {
            // auto segment
            pathSegment = [this.recordClass.getMeta('modelName'), Ext.util.Format.capitalize(this.addressType), 'Grid'].join(Tine.Tinebase.CanonicalPath.separator);
        }

        return pathSegment;
    },

    /**
     * called from this.clipboardAction
     * 
     * @param {Number} rowIndex
     */
    onCopyToClipboard: function(rowIndex) {
        var record = this.store.getAt(rowIndex);
        var companyName = this.editDialog.record.get('name');
        Tine.Sales.addToClipboard(record, companyName);
    },

    /**
     * overwrites and calls superclass
     * 
     * @param {Object} button
     * @param {Tine.Tinebase.data.Record} record
     * @param {Array} plugins
     */
    onEditInNewWindow: function(button, record, plugins) {
        // the name 'button' should be changed as this can be called in other ways also
        button.fixedFields = {
            'customer_id':  this.editDialog.record.data,
            'type':         this.addressType,
            'parentRecord': this.editDialog.record.data
        };
        
        var additionalConfig = {addressType: this.addressType};
        
        Tine.Sales.AddressGridPanel.superclass.onEditInNewWindow.call(this, button, record, plugins, additionalConfig);
    },
    
    
    /**
     * template method to allow adding custom columns
     * 
     * @return {Array}
     */
    getCustomColumns: function() {
        return [ this.clipboardAction ];
    }
});


/***/ }),

/***/ 753:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Address grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.DeliveryAddressGridPanel
 * @extends     Tine.Sales.AddressGridPanel
 * 
 * <p>Delivery Address Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * 
 * Create a new Tine.Sales.DeliveryAddressGridPanel
 */
Tine.Sales.DeliveryAddressGridPanel = Ext.extend(Tine.Sales.AddressGridPanel, {
    /**
     * inits this cmp
     * 
     * @private
     */
    initComponent: function() {
        this.addressType = 'delivery';
        
        // TODO use singular/plural translations here
        this.i18nRecordName  = this.app.i18n._('Delivery Address');
        this.i18nRecordsName = this.app.i18n._('Delivery Addresses');
        
        this.modelConfig = Ext.decode(Ext.encode(this.modelConfig));
        
        this.modelConfig.fields.custom1.label = null;
        
        Tine.Sales.DeliveryAddressGridPanel.superclass.initComponent.call(this);
    }
});


/***/ }),

/***/ 754:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Address grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.BillingAddressGridPanel
 * @extends     Tine.Sales.AddressGridPanel
 * 
 * <p>Billing Address Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * 
 * Create a new Tine.Sales.BillingAddressGridPanel
 */
Tine.Sales.BillingAddressGridPanel = Ext.extend(Tine.Sales.AddressGridPanel, {
    /**
     * inits this cmp
     * 
     * @private
     */
    initComponent: function() {
        this.addressType = 'billing';
        
        // TODO use singular/plural translations here
        this.i18nRecordName  = this.app.i18n._('Billing Address');
        this.i18nRecordsName = this.app.i18n._('Billing Addresses');
        
        Tine.Sales.BillingAddressGridPanel.superclass.initComponent.call(this);
    }
});


/***/ }),

/***/ 755:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.AddressEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Address Compose Dialog</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.AddressEditDialog
 */
Tine.Sales.AddressEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    /**
     * @private
     */
    tbarItems: null,
    evalGrants: false,
    
    windowWidth: 700,
    windowHeight: 400,

    displayNotes: true,
    
    /**
     * just update the contract grid panel, no persisten
     * 
     * @type String
     */
    mode: 'local',
    loadRecord: false,
    
    initComponent: function() {
        if (Ext.isString(this.additionalConfig)) {
            Ext.apply(this, Ext.decode(this.additionalConfig));
        }
        
        Tine.Sales.AddressEditDialog.superclass.initComponent.call(this);

        // code expect fixedFields to be present
        if (! this.fixedFields) {
            this.fixedFields = new Ext.util.MixedCollection();
        }
    },

    /**
     * returns canonical path part
     * @returns {string}
     */
    getCanonicalPathSegment: function () {
        return [
            this.supr().getCanonicalPathSegment.call(this),
            Ext.util.Format.capitalize(this.addressType)
        ].join(Tine.Tinebase.CanonicalPath.separator);
    },

    /**
     * executed after record got updated from proxy
     * 
     * @private
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        if (Ext.isString(this.record)) {
            this.record = this.recordProxy.recordReader({responseText: this.record});
        }
        
        this.record.set('customer_id', this.fixedFields.get('customer_id'));
        this.record.set('type',        String(this.fixedFields.get('type')).toLowerCase());
        
        Tine.Sales.AddressEditDialog.superclass.onRecordLoad.call(this);
        
        if (String(this.fixedFields.get('type')).toLowerCase() == 'billing') {
            this.i18nRecordName = this.app.i18n._('Billing Address');
            this.i18nRecordsName = this.app.i18n._('Billing Addresses');
        } else {
            this.i18nRecordName = this.app.i18n._('Delivery Address');
            this.i18nRecordsName = this.app.i18n._('Delivery Addresses');
        }
        
        if ((! this.copyRecord) && this.record.id) {
            var c = this.record.get('customer_id');
            var l = this.record.get('locality') ? ' (' + this.record.get('locality') + ')' : '';
            this.window.setTitle(String.format(i18n._('Edit {0} "{1}"'), this.i18nRecordName, c.name + l));
        } else if (! this.record.id) {
            if (String(this.fixedFields.get('type')).toLowerCase() == 'billing') {
                this.window.setTitle(this.app.i18n._('Add new Billing Address'));
            } else {
                this.window.setTitle(this.app.i18n._('Add new Delivery Address'));
            }
        }
    },
    
    /**
     * executed when record gets updated from form
     * 
     * @private
     */
    onRecordUpdate: function() {
        Tine.Sales.AddressEditDialog.superclass.onRecordUpdate.call(this);
        
        this.record.set('type',        String(this.fixedFields.get('type')).toLowerCase());
        this.record.set('customer_id', this.fixedFields.get('customer_id'));
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     * 
     * @return {Object}
     * @private
     */
    getFormItems: function() {
        var formFieldDefaults = {
            xtype:'textfield',
            anchor: '100%',
            labelSeparator: '',
            columnWidth: 1/2
        };
        
        
        var items = [
            [{
               columnWidth: .045,
               xtype:'button',
               iconCls: 'applyContactData',
               tooltip: Ext.util.Format.htmlEncode(this.app.i18n._('Apply postal address')),
               fieldLabel: '&nbsp;',
               lazyLoading: false,
               listeners: {
                    scope: this,
                    click: function() {
                        Ext.iterate(this.fixedFields.get('parentRecord'), function(property, value) {
                            var split = property.split(/_/);
                            if (split[0] == 'adr') {
                                if (value) {
                                    this.getForm().findField(split[1]).setValue(value);
                                }
                            }
                        }, this);
                    }
               }
            }, {
                columnWidth: 0.455,
                name: 'street',
                fieldLabel: this.app.i18n._('Street')
            }, {
                name: 'pobox',
                fieldLabel: this.app.i18n._('Postbox')
            }], [{
                name: 'postalcode',
                fieldLabel: this.app.i18n._('Postalcode')
            }, {
                name: 'locality',
                fieldLabel: this.app.i18n._('Locality')
            }], [{
                name: 'region',
                fieldLabel: this.app.i18n._('Region')
            }, {
                xtype: 'widget-countrycombo',
                name: 'countryname',
                fieldLabel: this.app.i18n._('Country')
            }], [{
                name: 'prefix1',
                fieldLabel: this.app.i18n._('Prefix')
            }, {
                name: 'prefix2',
                fieldLabel: this.app.i18n._('Additional Prefix')
            }]
        ];
        
        if (this.addressType == 'billing') {
            items.push([{
                name: 'custom1',
                fieldLabel: this.app.i18n._('Number Debit')
            }]);
        }
        
        return {
            xtype: 'tabpanel',
            defaults: {
                hideMode: 'offsets'
            },
            border: false,
            plain: true,
            activeTab: 0,
            items: [{
                title: this.app.i18n._('Address'),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    xtype: 'fieldset',
                    layout: 'hfit',
                    region: 'center',
                    autoHeight: true,
                    title: this.app.i18n._('Address'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: items
                    }]
                }]
            }]
        };
    }
});


/***/ }),

/***/ 756:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CustomerDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 * 
 * <p>Customer details Panel</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CustomerDetailsPanel
 */
Tine.Sales.CustomerDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
    
    /**
     * init
     */
    initComponent: function() {

        // init templates
        this.initTemplate();
        this.initDefaultTemplate();
        
        Tine.Sales.CustomerDetailsPanel.superclass.initComponent.call(this);
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Sales.CustomerDetailsPanel.superclass.afterRender.apply(this, arguments);
        
        if (this.felamimail === true) {
            this.body.on('click', this.onClick, this);
        }
    },
    
    /**
     * init default template
     * 
     * @todo: generalize this
     */
    initDefaultTemplate: function() {
        
        this.defaultTpl = new Ext.XTemplate(
            '<div class="preview-panel-timesheet-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-timesheet-left">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n.n_hidden('Customer', 'Customers', 3) + '</div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            this.app.i18n._('Select customer') + '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
                '<!-- Preview xxx -->',
                '<div class="preview-panel-timesheet-right">',
                    '<div class="bordercorner_gray_1"></div>',
                    '<div class="bordercorner_gray_2"></div>',
                    '<div class="bordercorner_gray_3"></div>',
                    '<div class="bordercorner_gray_4"></div>',
                    '<div class="preview-panel-declaration"></div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
            '</div>'        
        );
    },
    
    /**
     * init single contact template (this.tpl)
     */
    initTemplate: function() {
        this.tpl = new Ext.XTemplate(
            '<tpl for=".">',
                '<!-- Preview core data -->',
                '<div class="preview-panel preview-panel-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Core Data') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Customer Number') + '</span>{[this.encode(values.number)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Name') + '</span>{[this.encode(values.name)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Web') + '</span><a href="{[this.encode(values.url, "text")]}" target="_blank">{[this.encode(values.url, "text")]}</a><br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contact Person (external)') + '</span>{[this.encode(values.cpextern_id, "address")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contact Person (internal)') + '</span>{[this.encode(values.cpintern_id, "address")]}<br/>',
                        
                        
                    '</div>',
                '</div>',

                '<!-- Preview accounting data -->',
                '<div class="preview-panel preview-panel-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Accounting') + '</div>',
                    '<div>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('IBAN') + '</span>{[this.encode(values.iban)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('BIC') + '</span>{[this.encode(values.bic)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('VAT No.') + '</span>{[this.encode(values.vatid)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Currency') + '</span>{[this.encode(values.currency)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Currency Translation Rate') + '</span>{[this.encode(values.currency_trans_rate)]}<br/>',
                    '</div>',
                '</div>',
            
                '<!-- Preview description -->',
                '<div class="preview-panel-description preview-panel-left preview-panel-customer">',
                    '<div class="bordercorner_gray_1"></div>',
                    '<div class="bordercorner_gray_2"></div>',
                    '<div class="bordercorner_gray_3"></div>',
                    '<div class="bordercorner_gray_4"></div>',
                    '<div class="preview-panel-declaration">' + i18n._('Description') + '</div>',
                    '{[this.encode(values.description)]}',
                '</div>',
            '</tpl>',
            {
                /**
                 * encode
                 */
                encode: function(value, type, prefix) {
                    if (! value) {
                        return '';
                    }
                    type = type ? type : 'text';
                    switch (type) {
                        case 'text':
                            var ret = value;
                            break;
                        case 'address':
                            var ret = value.n_fn
                            break;
                    }
                    return Ext.util.Format.htmlEncode(ret);
                }
            }
        );
    }
});

/***/ }),

/***/ 757:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.SupplierDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 * 
 * <p>Supplier details Panel</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.SupplierDetailsPanel
 */
Tine.Sales.SupplierDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
    
    /**
     * init
     */
    initComponent: function() {

        // init templates
        this.initTemplate();
        this.initDefaultTemplate();
        
        Tine.Sales.SupplierDetailsPanel.superclass.initComponent.call(this);
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Sales.SupplierDetailsPanel.superclass.afterRender.apply(this, arguments);
        
        if (this.felamimail === true) {
            this.body.on('click', this.onClick, this);
        }
    },
    
    /**
     * init default template
     * 
     * @todo: generalize this
     */
    initDefaultTemplate: function() {
        
        this.defaultTpl = new Ext.XTemplate(
            '<div class="preview-panel-timesheet-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-timesheet-left">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n.n_hidden('Supplier', 'Suppliers', 3) + '</div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            this.app.i18n._('Select supplier') + '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
                '<!-- Preview xxx -->',
                '<div class="preview-panel-timesheet-right">',
                    '<div class="bordercorner_gray_1"></div>',
                    '<div class="bordercorner_gray_2"></div>',
                    '<div class="bordercorner_gray_3"></div>',
                    '<div class="bordercorner_gray_4"></div>',
                    '<div class="preview-panel-declaration"></div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
            '</div>'        
        );
    },
    
    /**
     * init single contact template (this.tpl)
     */
    initTemplate: function() {
        this.tpl = new Ext.XTemplate(
            '<tpl for=".">',
                '<!-- Preview core data -->',
                '<div class="preview-panel preview-panel-left preview-panel-supplier">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Core Data') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Supplier Number') + '</span>{[this.encode(values.number)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Name') + '</span>{[this.encode(values.name)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Web') + '</span><a href="{[this.encode(values.url, "text")]}" target="_blank">{[this.encode(values.url, "text")]}</a><br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contact Person (external)') + '</span>{[this.encode(values.cpextern_id, "address")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contact Person (internal)') + '</span>{[this.encode(values.cpintern_id, "address")]}<br/>',
                        
                        
                    '</div>',
                '</div>',

                '<!-- Preview accounting data -->',
                '<div class="preview-panel preview-panel-left preview-panel-supplier">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Accounting') + '</div>',
                    '<div>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('IBAN') + '</span>{[this.encode(values.iban)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('BIC') + '</span>{[this.encode(values.bic)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('VAT No.') + '</span>{[this.encode(values.vatid)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Currency') + '</span>{[this.encode(values.currency)]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Currency Translation Rate') + '</span>{[this.encode(values.currency_trans_rate)]}<br/>',
                    '</div>',
                '</div>',
            
                '<!-- Preview description -->',
                '<div class="preview-panel-description preview-panel-left preview-panel-supplier">',
                    '<div class="bordercorner_gray_1"></div>',
                    '<div class="bordercorner_gray_2"></div>',
                    '<div class="bordercorner_gray_3"></div>',
                    '<div class="bordercorner_gray_4"></div>',
                    '<div class="preview-panel-declaration">' + i18n._('Description') + '</div>',
                    '{[this.encode(values.description)]}',
                '</div>',
            '</tpl>',
            {
                /**
                 * encode
                 */
                encode: function(value, type, prefix) {
                    if (! value) {
                        return '';
                    }
                    type = type ? type : 'text';
                    switch (type) {
                        case 'text':
                            var ret = value;
                            break;
                        case 'address':
                            var ret = value.n_fn
                            break;
                    }
                    return Ext.util.Format.htmlEncode(ret);
                }
            }
        );
    }
});

/***/ }),

/***/ 758:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Customer grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CustomerGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Customer Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.CustomerGridPanel
 */
Tine.Sales.CustomerGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    
    initComponent: function() {
        this.initDetailsPanel();
        Tine.Sales.CustomerGridPanel.superclass.initComponent.call(this);
    },

    /**
     * @private
     */
    initDetailsPanel: function() {
        this.detailsPanel = new Tine.Sales.CustomerDetailsPanel({
            grid: this,
            app: this.app
        });
    }
});


/***/ }),

/***/ 759:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Supplier grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.SupplierGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Supplier Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.SupplierGridPanel
 */
Tine.Sales.SupplierGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    
    initComponent: function() {
        this.initDetailsPanel();
        Tine.Sales.SupplierGridPanel.superclass.initComponent.call(this);
    },

    /**
     * @private
     */
    initDetailsPanel: function() {
        this.detailsPanel = new Tine.Sales.SupplierDetailsPanel({
            grid: this,
            app: this.app
        });
    }
});


/***/ }),

/***/ 760:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ExceptionHandler
 * 
 * <p>Exception Handler for Sales</p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */

Tine.Sales.handleRequestException = function(exception, callback, callbackScope) {
    if (! exception.code && exception.responseText) {
        // we need to decode the exception first
        var response = Ext.util.JSON.decode(exception.responseText);
        exception = response.data;
    }
    
    var app = Tine.Tinebase.appMgr.get('Sales');
    
    var defaults = {
        buttons: Ext.Msg.OK,
        icon: Ext.MessageBox.ERROR,
        fn: callback,
        scope: callbackScope,
        title: app.i18n._(exception.title),
        msg: app.i18n._(exception.message)
    };
    
    Tine.log.warn('Request exception :');
    Tine.log.warn(exception);

    switch(exception.code) {
        case 910: // Sales_Exception_UnknownCurrencyCode
        case 911: // Sales_Exception_DuplicateNumber
        case 913: // Sales_Exception_InvoiceAlreadyClearedEdit
        case 914: // Sales_Exception_InvoiceAlreadyClearedDelete
        case 915: // Sales_Exception_AlterOCNumberForbidden
        case 916: // Sales_Exception_DeletePreviousInvoice
            Ext.MessageBox.show(defaults);
            return true;
            break;
        case 917: // Sales_Exception_DeleteUsedBillingAddress
            var app = Tine.Tinebase.appMgr.get('Sales');
            var storeData = {
                results: exception.contracts,
                totalcount: exception.contracts.length
            };
                
            var window = Tine.widgets.dialog.ExceptionHandlerDialog.openWindow({
                height: 245,
                messageHeight: 70,
                exception: exception,
                type: 'error',
                
                callback: function() {
                    location.reload();
                },
                
                fields: [[{
                    xtype: 'grid',
                    height: 110,
                    autoExpandColumn: 'title',
                    listeners: { 
                        scope: this,
                        rowdblclick: function(grid, index, event) {
                            Tine.Sales.ContractEditDialog.openWindow({record: grid.store.getAt(index)});
                        }
                    },
                    store: new Ext.data.Store({
                        data: storeData,
                        reader: new Ext.data.JsonReader({
                            id: 'id',
                            root: 'results',
                            totalProperty: 'totalcount'
                        }, Tine.Sales.Model.Contract)
                    }),
                    
                    title: null,
                    columns: [{
                        id: 'number',
                        dataIndex: 'number',
                        header: app.i18n._('Number'),
                        sortable: true
                    }, {
                        id: 'title',
                        dataIndex: 'title',
                        header: app.i18n._('Title'),
                        sortable: true
                    }]
                }]]
            });
            
            return true;
            break;
        // return false will the generic exceptionhandler handle the caught exception
        default:
            return false;
    }
    
    return true;
}

Tine.Tinebase.ExceptionHandlerRegistry.register('Sales', Tine.Sales.handleRequestException);

/***/ }),

/***/ 761:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
Ext.namespace('Tine.Sales');

/**
 * Copy Address Dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CopyAddressDialog
 * @extends     Ext.FormPanel
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @constructor
 * @param {Object} config The configuration options.
 */

Tine.Sales.CopyAddressDialog = Ext.extend(Ext.FormPanel, {
    
    // private
    layout : 'fit',
    border : false,
    cls : 'tw-editdialog',
    labelAlign : 'top',
    anchor : '100% 100%',
    deferredRender : false,
    buttonAlign : null,
    bufferResize : 500,
    
    /**
     * the calling application
     * 
     * @type Tine.Tinebase.Application
     */
    app: null,
    
    initComponent: function() {
        this.initActions();
        this.initButtons();
        this.initFormItems();
        
        Tine.Sales.CopyAddressDialog.superclass.initComponent.call(this);
        
        this.getForm().findField('content').setValue(this.content);
        this.getForm().findField('content').focus(true, 200);
    },
    
    /**
     * create the buttons
     */
    initButtons : function() {
        this.fbar = [ '->', this.action_update];
    },
    
    /**
     * populates this.items with the form items
     */
    initFormItems: function() {
        this.items = {
            title: null,
            border: false,
            frame: true,
            layout: 'border',
            cls: 'x-window-dlg',
            items: [{
                title: null,
                region: 'center',
                xtype: 'columnform',
                labelAlign: 'top',
                items: [[{
                    fieldLabel: this.app.i18n.n_('Address', 'Addresses', 1),
                    xtype: 'textarea',
                    name: 'content',
                    anchor: '100%',
                    height: 120,
                    labelSeparator: '',
                    columnWidth: 1,
                    allowBlank: true
                }]]
            }]
        };
    },
    
    /**
     * is called on render, creates keymap
     * @param {} ct
     * @param {} position
     */
    onRender : function(ct, position) {
        Tine.Sales.CopyAddressDialog.superclass.onRender.call(this, ct, position);

        // generalized keybord map for edit dlgs
        new Ext.KeyMap(ct, [ {
            key : [ 10, 13 ], // ctrl + return
            ctrl : true,
            fn : this.onOk,
            scope : this
        }]);
        
        this.window.setTitle(this.app.i18n._hidden(this.winTitle));
    },
    
    /**
     * called on clicking the OK button
     */
    onOk: function() {
        this.window.close();
        this.onClose();
    },
    
    /**
     * initializes the actions
     */
    initActions: function() {
        this.action_update = new Ext.Action({
            text : i18n._('Ok'),
            minWidth : 70,
            scope : this,
            handler: this.onOk,
            iconCls : 'action_saveAndClose'
        });
    }
});


/**
 * @param {Object}
 * 
 * @return {Ext.ux.Window}
 */
Tine.Sales.CopyAddressDialog.openWindow = function(config) {
    var window = Tine.WindowFactory.getExtWindow({
        title: config.winTitle,
        width : 290,
        height : 225,
        contentPanelConstructor : 'Tine.Sales.CopyAddressDialog',
        contentPanelConstructorConfig : config
    });
    
    return window;
};

/***/ }),

/***/ 762:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * OrderConfirmation edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.OrderConfirmationEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>OrderConfirmation Edit Dialog</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.OrderConfirmationGridPanel
 */
Tine.Sales.OrderConfirmationEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    windowWidth: 650,
    windowHeight: 350,

    displayNotes: true,
    
    
    /**
     * init component
     */
    initComponent: function () {
        Tine.Sales.OrderConfirmationEditDialog.superclass.initComponent.call(this);
    },

    /**
     * called on multiple edit
     * @return {Boolean}
     */
    isMultipleValid: function() {
        return true;
    },
    
    /**
     * @see: Tine.widgets.dialog.EditDialog.onRecordLoad
     */
    onRecordLoad: function() {
        Tine.Sales.OrderConfirmationEditDialog.superclass.onRecordLoad.call(this);
        
        if (! this.copyRecord && ! this.record.id) {
            this.window.setTitle(this.app.i18n._('Add New Order Confirmation'));
        }
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            defaults: {
                hideMode: 'offsets'
            },
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Order Confirmation', 'Order Confirmations', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: 1/2
                    },
                    items: [[{
                        fieldLabel: this.app.i18n._('Number'),
                        name: 'number',
                        disabled: (! Tine.Tinebase.common.hasRight('change', 'Sales', 'oc_number') && this.record.id),
                        allowBlank: true // autoset if empty
                    },{
                        fieldLabel: this.app.i18n._('Title'),
                        name: 'title',
                        allowBlank: false
                    }], [{
                            xtype: 'tinerelationpickercombo',
                            fieldLabel: this.app.i18n._('Contract'),
                            editDialog: this,
                            allowBlank: false,
                            app: 'Sales',
                            recordClass: Tine.Sales.Model.Contract,
                            relationType: 'CONTRACT',
                            relationDegree: 'sibling',
                            modelUnique: true,
                            columnWidth: 1
                        }], [{
                            xtype: 'tinerelationpickercombo',
                            fieldLabel: this.app.i18n._('Offer'),
                            editDialog: this,
                            allowBlank: true,
                            app: 'Sales',
                            recordClass: Tine.Sales.Model.Offer,
                            relationType: 'OFFER',
                            relationDegree: 'sibling',
                            modelUnique: true,
                            columnWidth: 1
                        }]
                    ]
                }, {
                    // activities and tags
                    layout: 'ux.multiaccordion',
                    animate: true,
                    region: 'east',
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                        new Ext.Panel({
                            title: this.app.i18n._('Description'),
                            iconCls: 'descriptionIcon',
                            layout: 'form',
                            labelAlign: 'top',
                            border: false,
                            items: [{
                                style: 'margin-top: -4px; border 0px;',
                                labelSeparator: '',
                                xtype: 'textarea',
                                name: 'description',
                                hideLabel: true,
                                grow: false,
                                preventScrollbars: false,
                                anchor: '100% 100%',
                                emptyText: this.app.i18n._('Enter description'),
                                requiredGrant: 'editGrant'
                            }]
                        }),
                        new Tine.widgets.tags.TagPanel({
                            app: 'Sales',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            }, new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: 'Sales_Model_OrderConfirmation'
            })]
        };
    }
});


/***/ }),

/***/ 763:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.ContractFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'contract',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Contract');
        this.foreignRecordClass = Tine.Sales.Model.Contract;
        this.pickerConfig = {emptyText: this.app.i18n._('without contract'), allowBlank: true};
        Tine.Sales.ContractFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.invoicecontract']  = Tine.Sales.ContractFilterModel;
Tine.widgets.grid.FilterToolbar.FILTERS['sales.orderconfirmation-contract']  = Tine.Sales.ContractFilterModel;


/***/ }),

/***/ 764:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.CustomerFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.CustomerFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'customer',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Customer');
        this.foreignRecordClass = Tine.Sales.Model.Customer;
        this.pickerConfig = {emptyText: this.app.i18n._('without customer'), allowBlank: true};
        Tine.Sales.CustomerFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.invoicecustomer']  = Tine.Sales.CustomerFilterModel;
Tine.widgets.grid.FilterToolbar.FILTERS['sales.offer-customer']  = Tine.Sales.CustomerFilterModel;

/***/ }),

/***/ 765:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.SupplierFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.SupplierFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'supplier',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Supplier');
        this.foreignRecordClass = Tine.Sales.Model.Supplier;
        this.pickerConfig = {emptyText: this.app.i18n._('without supplier'), allowBlank: true};
        Tine.Sales.SupplierFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.supplier']  = Tine.Sales.SupplierFilterModel;


/***/ }),

/***/ 766:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3 @author
 * Alexander Stintzing <a.stintzing@metaways.de> @copyright Copyright (c) 2013
 * Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace Tine.Sales
 * @class Tine.Sales.InvoiceEditDialog
 * @extends Tine.widgets.dialog.EditDialog
 * 
 * <p>
 * Invoice Compose Dialog
 * </p>
 * <p>
 * </p>
 * 
 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param {Object}
 *            config
 * @constructor Create a new Tine.Sales.InvoiceEditDialog
 */
Tine.Sales.InvoiceEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    /**
     * @private
     */
    tbarItems: null,
    evalGrants: false,
    
    /**
     * autoset
     * 
     * @type combo
     */
    addressPicker: null,
    
    /**
     * autoset
     * 
     * @type combo
     */
    customerPicker: null,
    
    /**
     * autoset
     * 
     * @type combo
     */
    contractPicker: null,
    
    createReversal: false,
    
    windowWidth: 800,
    windowHeight: 700,

    displayNotes: true,
    
    initComponent: function() {
        if (!this.app) {
            this.app = Tine.Tinebase.appMgr.get('Sales');
        }

        this.createTimesheetAction = new Ext.Action({
            requiredGrant: 'exportGrant',
            text: this.app.i18n._('Create timesheet'),
            minWidth: 70,
            scope: this,
            handler: this.onCreateTimesheet,
            actionUpdater: function (action, grants, records, isFilterSelect) {
                if (action.initialConfig.requiredGrant) {
                    if (grants[action.initialConfig.requiredGrant] === false) {
                        action.setDisabled(true);
                        return;
                    }
                }

                // only persistent records can do this
                action.setDisabled(!this.record.id);
            },
            iconCls: 'action_next'
        });
        
        this.tbarItems = this.tbarItems || [];
        this.tbarItems.push(this.createTimesheetAction);

        Tine.Sales.InvoiceEditDialog.superclass.initComponent.call(this);
    },

    onCreateTimesheet: function () {
        var me = this;

        me.loadMask.show();

        Tine.Sales.createTimesheetForInvoice(me.record.id).then(function (res) {
            me.recordFromJson = true;
            me.record = JSON.stringify(res);
            me.initRecord();
        }).then(function () {
            me.loadMask.hide();
        }).catch(function () {
            me.loadMask.hide();
        });
    },
    
    /**
     * executed after record got updated from proxy
     * 
     * @private
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        if (this.record.get('sales_tax') == null) {
            this.record.set('sales_tax', 19);
        }
        
        if (this.createReversal) {
            var originalRecord = this.recordProxy.recordReader({responseText: Ext.encode(this.record.data)}); ;
            
            this.record.set('cleared', 'TO_CLEAR');
            this.record.set('number', null);
            this.record.set('date', null);
            this.record.set('type', 'REVERSAL');
            this.record.set('positions', []);

            this.record.set('price_gross', this.record.get('price_gross') * -1);
            this.record.set('price_net', this.record.get('price_net') * -1);

            var relations = this.record.get('relations');
            var newRelations = [];
            var allowedRelations = ['Sales_Model_Customer', 'Sales_Model_CostCenter', 'Sales_Model_Contract'];
            Ext.each(relations, function(relation, index) {
                if (allowedRelations.indexOf(relation.related_model) > -1) {
                    relation.id = null;
                    newRelations.push(relation);
                }
            });
            
            newRelations.push({
                related_degree:  'sibling',
                own_backend:     'Sql',
                related_id:      originalRecord.get('id'),
                related_record:  originalRecord.data,
                related_model:   'Sales_Model_Invoice',
                related_backend: 'Sql',
                own_model:       'Sales_Model_Invoice',
                type:            'REVERSAL'
            });
            
            this.record.set('relations', newRelations);
        }
        
        // this will start preparing the gridpanels for the invoice positions
        if (this.positionsPanel) {
            this.positionsPanel.positions = this.record.get('positions');
            this.positionsPanel.invoiceId = this.record.get('id');
        }
        
        Tine.Sales.InvoiceEditDialog.superclass.onRecordLoad.call(this);

        if (this.createReversal) {
            this.window.setTitle(this.app.i18n._('Create Reversal Invoice'));
            this.doCopyRecord();
        } else if (this.copyRecord) {
            this.doCopyRecord();
            this.window.setTitle(this.app.i18n._('Copy Invoice'));
        } else {
            if (! this.record.id) {
                this.window.setTitle(this.app.i18n._('Add New Invoice'));
            } else {
                this.window.setTitle(String.format(this.app.i18n._('Edit Invoice "{0}"'), this.record.getTitle()));
            }
        }

        if (this.record.id || this.createReversal) {
            var form = this.getForm();
            var ar = ['type', 'contract'];
            for (var index = 0; index < ar.length; index++) {
                form.findField(ar[index]).setReadOnly(1);
            }
        }
        
        if (this.record.get('cleared') == 'CLEARED') {
            var ar = ['credit_term', 'costcenter_id', 'cleared', 'type'];
            for (var index = 0; index < ar.length; index++) {
                form.findField(ar[index]).setReadOnly(1);
            }
        }
        
        this.onAddressLoad();
        if (this.positionsPanel) {
            this.positionsPanel.setTitle(this.app.i18n._('Positions') + ' (' +  (Ext.isArray(this.record.data.positions) ? this.record.data.positions.length : 0) + ')');
        }
    },
    
    /**
     * loads the address to the plaintext field
     */
    onAddressLoad: function(combo, record) {
        if (Ext.isEmpty(this.record.get('number'))) {
            var billingAddress = record;
            if (! billingAddress && this.record.get('address_id')) {
                billingAddress = new Tine.Sales.Model.Address(this.record.get('address_id'));
            }
            if (billingAddress) {
                var companyName = this.record.get('customer') ? this.record.get('customer').name : null;
                if (! companyName && this.record.get('customer_id') && this.record.get('customer_id').name) {
                    companyName = this.record.get('customer_id').name;
                }
                if (! companyName && billingAddress.get('customer')) {
                    companyName = billingAddress.get('customer') && billingAddress.get('customer').name
                        ? billingAddress.get('customer').name
                        : null;
                }
                this.form.findField('fixed_address').setValue(Tine.Sales.renderAddress(billingAddress, companyName));
            }
        }
    },
    
    /**
     * loads the full-featured record, if a contract gets selected
     * 
     * @param {Tine.widgets.relation.PickerCombo}
     *            combo
     * @param {Tine.Sales.Model.Contract}
     *            record
     * @param {Number}
     *            index
     */
    onContractLoad: function(combo, record, index) {
        // here we fetch the record again to have the related customer, where we
        // can find the address for
        var proxy = Tine.Sales.contractBackend;
        
        proxy.loadRecord(record, {
            scope: this,
            success: this.onAfterContractLoad,
            failure: Tine.Tinebase.ExceptionHandler.handleRequestException
        });
    },
    
    /**
     * 
     * @param {Tine.Sales.Model.Contract}
     *            record
     */
    onAfterContractLoad: function(record, customer) {
        var record = record ? record : this.record;
        var relations = record.get('relations'), foundCostCenter = false;
        var foundCustomer = customer ? customer : null;
        
        if (Ext.isArray(relations)) {
            for (var index = 0; index < relations.length; index++) {
                if (foundCostCenter && foundCustomer) {
                    break;
                }
                if (! foundCustomer && relations[index].related_model == 'Sales_Model_Customer' && relations[index].type == 'CUSTOMER') {
                    foundCustomer = relations[index].related_record;
                } else if (! foundCostCenter && relations[index].related_model == 'Sales_Model_CostCenter' && relations[index].type == 'LEAD_COST_CENTER') {
                    foundCostCenter = relations[index].related_record;
                }
            }
        }

        // set description to contract title if empty
        var descriptionField = this.getForm().findField('description');
        if (descriptionField.getValue() == '') {
            descriptionField.setValue(record.get('title'));
        }

        if (foundCustomer) {
            this.customerPicker.setValue(foundCustomer);
            this.customerPicker.combo.fireEvent('select');
            
            if (this.addressPicker.disabled) {
                this.addressPicker.enable();
                
                if (record.get('billing_address_id')) {
                    var billingAddress = record.get('billing_address_id');
                    if (! billingAddress.data) {
                        billingAddress = new Tine.Sales.Model.Address(billingAddress);
                    }
                    billingAddress.set('customer', foundCustomer);
                    this.addressPicker.setValue(billingAddress);
                    this.onAddressLoad(this.addressPicker, billingAddress);
                }
            } else {
                this.addressPicker.reset();
            }
            this.addressPicker.lastQuery = null;
            
            this.addressPicker.additionalFilters = [
                {field: 'type', operator: 'not', value: 'delivery'},
                {field: 'customer_id', operator: 'AND', value: [
                    {field: ':id', operator: 'in', value: [foundCustomer.id]}
                ]}
            ];
            
            this.getForm().findField('credit_term').setValue(foundCustomer.credit_term);

        } else {
            Ext.MessageBox.show({
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.WARNING,
                title: this.app.i18n._('No customer assigned'), 
                msg: this.app.i18n._("The selected contract doesn't have a customer assigned, yet. Add a customer to the contract with the contract edit dialog.")
            });
        }
        
        if (foundCostCenter) {
            this.getForm().findField('costcenter_id').setValue(foundCostCenter);
        } else {
            if (! this.record.get('costcenter_id')) {
                Ext.MessageBox.show({
                    buttons: Ext.Msg.OK,
                    icon: Ext.MessageBox.WARNING,
                    title: this.app.i18n._('No cost center assigned'), 
                    msg: this.app.i18n._("The selected contract doesn't have a cost center assigned, yet. Add a cost center to the contract with the contract edit dialog.")
                });
            }
        }
    },
    
    /**
     * calculates price gross by price net and tax
     */
    calcGross: function() {
        var net = parseFloat(this.priceNetField.getValue());
        var negative = false;
        if (net < 0) {
            net = Math.abs(net);
            negative = true;
        }
        var tax = parseFloat(this.salesTaxField.getValue());
        tax = Math.round(net * (tax / 100) * 100) / 100;
        if (negative) {
            tax = 0 - tax;
            net = 0 - net;
        }
        var gross = net + tax;

        this.priceTaxField.setValue(tax);
        this.priceGrossField.setValue(gross);
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     * 
     * @return {Object}
     * @private
     */
    getFormItems: function() {
        var formFieldDefaults = {
            xtype: 'textfield',
            anchor: '100%',
            labelSeparator: '',
            columnWidth: .5
        };
        
        if (this.record.get('is_auto') == 1) {
            this.positionsPanel = new Tine.Sales.InvoicePositionPanel({
                app: this.app,
                title: null
            });
        }
        
        this.priceNetField = new Ext.ux.form.NumberField({
            name: 'price_net',
            xtype: 'numberfield',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            decimalPrecision: 2,
            suffix: ' €',
            fieldLabel: this.app.i18n._('Price Net'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.calcGross.createDelegate(this)
            }
        });

        this.priceTaxField = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_tax',
            disabled: true,
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Price Tax'),
            columnWidth: 1/4
        });
        
        this.priceGrossField = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_gross',
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Price Gross'),
            columnWidth: 1/4
        });
        
        this.salesTaxField = Ext.create({
            xtype: 'uxspinner',
            decimalPrecision: 2,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 0.1,
                alternateIncrementValue: 1,
                minValue: 0,
                maxValue: 100,
                allowDecimals: 2
            }),
            name: 'sales_tax',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            regex: /^[0-9]+\.?[0-9]*$/,
            fieldLabel: this.app.i18n._('Sales Tax (percent)'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                spin: this.calcGross.createDelegate(this),
                blur: this.calcGross.createDelegate(this)
            }
        });
        
        this.inventoryChange = new Ext.ux.form.NumberField({
            name: 'inventory_change',
            xtype: 'numberfield',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            decimalPrecision: 2,
            suffix: ' €',
            fieldLabel: this.app.i18n._('Inventory Change'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.calcGross.createDelegate(this)
            }
        });
        
        var items = [{
            title: this.app.i18n._('Invoice'),
            autoScroll: true,
            border: false,
            frame: true,
            layout: 'border',
            items: [{
                region: 'center',
                layout: 'hfit',
                border: false,
                items: [{
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Invoice'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [[
                        {
                            name: 'number',
                            fieldLabel: this.app.i18n._('Invoice Number'),
                            columnWidth: 1/3,
                            readOnly: ! Tine.Tinebase.common.hasRight('set_invoice_number', 'Sales'),
                            emptyText: this.app.i18n._('automatically set...')
                        }, {
                            xtype: 'datefield',
                            name: 'date',
                            fieldLabel: this.app.i18n._('Date'),
                            columnWidth: 1/3,
                            emptyText: (this.record.get('is_auto') == 1) ? this.app.i18n._('automatically set...') : ''
                        }, new Tine.Tinebase.widgets.keyfield.ComboBox({
                            app: 'Sales',
                            keyFieldName: 'invoiceType',
                            fieldLabel: this.app.i18n._('Type'),
                            name: 'type',
                            columnWidth: 1/3
                        })], [{
                            name: 'description',
                            fieldLabel: this.app.i18n._('Description'),
                            columnWidth: 1,
                            allowBlank: false
                        }], [{
                            fieldLabel: this.app.i18n._('Contract'),
                            columnWidth: 1,
                            listeners: {
                                scope: this,
                                select: this.onContractLoad
                            },
                            editDialog: this,
                            xtype: 'tinerelationpickercombo',
                            allowBlank: false,
                            app: 'Sales',
                            recordClass: Tine.Sales.Model.Contract,
                            relationType: 'CONTRACT',
                            relationDegree: 'sibling',
                            modelUnique: true,
                            ref: '../../../../../../../contractPicker',
                            name: 'contract'
                        }], [{
                            fieldLabel: this.app.i18n._('Customer'),
                            columnWidth: 1,
                            editDialog: this,
                            xtype: 'tinerelationpickercombo',
                            allowBlank: false,
                            app: 'Sales',
                            recordClass: Tine.Sales.Model.Customer,
                            relationType: 'CUSTOMER',
                            relationDegree: 'sibling',
                            modelUnique: true,
                            ref: '../../../../../../../customerPicker',
                            readOnly: true,
                            name: 'customer'
                        }],[
                            Tine.widgets.form.RecordPickerManager.get('Sales', 'Address', {
                                fieldLabel: this.app.i18n._('Billing Address'),
                                name: 'address_id',
                                ref: '../../../../../../../addressPicker',
                                columnWidth: 1,
                                disabled: true,
                                allowBlank: false,
                                listeners: {
                                    scope: this,
                                    select: this.onAddressLoad.createDelegate(this)
                                }
                            })
                        ], [{
                            columnWidth: 1,
                            fieldLabel: '',
                            name: 'fixed_address',
                            xtype: 'textarea',
                            height: 100,
                            readOnly: true
                        }
                        ]]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Miscellaneous'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                fieldLabel: this.app.i18n._('Credit Term'),
                                name: 'credit_term',
                                allowBlank: false,
                                xtype: 'uxspinner',
                                strategy: new Ext.ux.form.Spinner.NumberStrategy({
                                    incrementValue : 1,
                                    alternateIncrementValue: 10,
                                    minValue: 0,
                                    maxValue: 1024,
                                    allowDecimals: false
                                })
                            }, Tine.widgets.form.RecordPickerManager.get('Sales', 'CostCenter', {
                                    columnWidth: 1/2,
                                    blurOnSelect: true,
                                    allowBlank: false,
                                    fieldLabel: this.app.i18n.n_('Cost Center', 'Cost Centers', 1),
                                    name: 'costcenter_id'
                            })], [
                                new Tine.Tinebase.widgets.keyfield.ComboBox({
                                    app: 'Sales',
                                    keyFieldName: 'invoiceCleared',
                                    fieldLabel: this.app.i18n._('Cleared'),
                                    name: 'cleared',
                                    allowBlank: false,
                                    columnWidth: 1/3
                                }), {
                                    xtype: 'datefield',
                                    name: 'start_date',
                                    fieldLabel: this.app.i18n._('Interval Begins'),
                                    columnWidth: 1/3
                                }, {
                                    xtype: 'datefield',
                                    name: 'end_date',
                                    fieldLabel: this.app.i18n._('Interval Ends'),
                                    columnWidth: 1/3
                                }
                            ], [
                                this.priceNetField,
                                this.salesTaxField,
                                this.priceTaxField,
                                this.priceGrossField
                            ],
                            [
                                this.inventoryChange
                            ]
                        ]
                    }]
                }]
            }, {
                // activities and tags
                layout: 'ux.multiaccordion',
                animate: true,
                region: 'east',
                width: 210,
                split: true,
                collapsible: true,
                collapseMode: 'mini',
                header: false,
                margins: '0 5 0 5',
                border: true,
                items: [
                    new Tine.widgets.tags.TagPanel({
                        app: 'Sales',
                        border: false,
                        bodyStyle: 'border:1px solid #B5B8C8;'
                    })
                ]
            }]
        }];
        
        if (this.positionsPanel) {
            items.push(this.positionsPanel);
        }
        
        items.push(new Tine.widgets.activities.ActivitiesTabPanel({
            app: this.appName,
            record_id: this.record.id,
            record_model: 'Sales_Model_Invoice'
        }));
        
        return {
            xtype: 'tabpanel',
            defaults: {
                hideMode: 'offsets'
            },
            border: false,
            plain: true,
            activeTab: 0,
            items: items
        };
    }
});


/***/ }),

/***/ 767:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3 @author
 * Alexander Stintzing <a.stintzing@metaways.de> @copyright Copyright (c) 2013
 * Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace Tine.Sales
 * @class Tine.Sales.PurchaseInvoiceEditDialog
 * @extends Tine.widgets.dialog.EditDialog
 * 
 * <p>
 * Invoice Compose Dialog
 * </p>
 * <p>
 * </p>
 * 
 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param {Object}
 *            config
 * @constructor Create a new Tine.Sales.PurchaseInvoiceEditDialog
 */
Tine.Sales.PurchaseInvoiceEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    /**
     * @private
     */
    evalGrants: false,
    
    windowWidth: 900,
    windowHeight: 700,
    displayNotes: true,
    
    /**
     * is form valid?
     * 
     * @return {Boolean}
     */
    isValid: function() {
        return Tine.Sales.PurchaseInvoiceEditDialog.superclass.isValid.call(this);
    },
    
    /**
     * executed after record got updated from proxy
     * 
     * @private
     */
    onRecordLoad: function() {
        // interrupt process flow until dialog is rendered
        if (! this.rendered) {
            this.onRecordLoad.defer(250, this);
            return;
        }
        
        Tine.Sales.PurchaseInvoiceEditDialog.superclass.onRecordLoad.call(this);

        if (this.copyRecord) {
            this.doCopyRecord();
            this.window.setTitle(this.app.i18n._('Copy Purchase Invoice'));
        } else {
            if (! this.record.id) {
                this.window.setTitle(this.app.i18n._('Add New Purchase Invoice'));
            } else {
                this.window.setTitle(String.format(this.app.i18n._('Edit Purchase Invoice "{0}"'), this.record.getTitle()));
            }
        }
        
        // mark some fields as read only
        /*if (this.record.id) {
            var form = this.getForm();
            var ar = ['type', 'contract'];
            for (var index = 0; index < ar.length; index++) {
                form.findField(ar[index]).setReadOnly(1);
            }
        }*/
        
        // mark some more fields as read only
        /*if (this.record.get('cleared') == 'CLEARED') {
            var ar = ['credit_term', 'costcenter_id', 'cleared', 'type'];
            for (var index = 0; index < ar.length; index++) {
                form.findField(ar[index]).setReadOnly(1);
            }
        }*/
    },
    
    onUpdatePriceNet: function() {
        this.calcTax();
        this.calcGross();
        this.calcTotal();
    },
    
    onUpdateSalesTax: function() {
        this.calcTax();
        this.calcGross();
        this.calcTotal();
    },
    
    onUpdatePriceTax: function() {
        this.calcTaxPercent();
        this.calcGross();
        this.calcTotal();
    },
    
    onUpdateDateOfInvoice: function() {
        var dateOfInvoice = this.dateOfInvoiceField.getValue();
        var dueInDays     = parseInt(this.dueInDaysField.getValue());
        
        var dueDate =  dateOfInvoice.clone().add(Date.DAY, dueInDays);
        
        this.dueAtField.setValue(dueDate);
    },
    
    onUpdateInDays: function() {
        this.onUpdateDateOfInvoice();
    },
    
    onUpdateDueAt: function() {
        var dateOfInvoice = this.dateOfInvoiceField.getValue();
        var dueAt         = this.dueAtField.getValue();
        
        // @todo needs improvement 
        // result is incorrect when dueAt is before dateOfInvoice
        // Math.round is used mitigate timeshift changes
        var timeDiff = Math.abs(dueAt.getTime() - dateOfInvoice.getTime());
        var diffDays = Math.round(timeDiff / (1000 * 3600 * 24));
        
        this.dueInDaysField.setValue(diffDays);
    },

    /**
     * calculates total prices by price gross, additional price gross, discount
     */
    calcTotal: function() {
        var priceGross      = parseFloat(this.priceGrossField.getValue());
        var priceGross2     = parseFloat(this.priceGross2Field.getValue());
        var discount        = parseFloat(this.discountField.getValue());

        var total = (priceGross + priceGross2) * (1 - discount/100) * 100;
        var negative = false;
        if (total < 0) {
            negative = true;
            total = Math.abs(total);
        }
        total = Math.round( total ) / 100;
        if ( negative ) {
            total = 0 - total;
        }

        this.priceTotalField.setValue( total );
    },

    /**
     * calculates price gross by price net and tax
     */
    calcGross: function() {
        var netPrice = parseFloat(this.priceNetField.getValue());
        var tax      = parseFloat(this.priceTaxField.getValue());
        
        this.priceGrossField.setValue(netPrice + tax);
    },
    
    /**
     * calculates price gross by price net and tax
     */
    calcTax: function() {
        var netPrice   = parseFloat(this.priceNetField.getValue());
        var taxPercent = parseFloat(this.salesTaxField.getValue());
        
        var tax        = netPrice * (taxPercent / 100);
        var negative = false;
        if (tax < 0) {
            tax = Math.abs(tax);
            negative = true;
        }
        var roundedTax = Math.round(tax * 100) / 100;
        if ( negative ) {
            roundedTax = 0 - roundedTax;
        }
        
        this.priceTaxField.setValue(roundedTax);
    },
    
    /**
     * calculates price gross by price net and tax
     */
    calcTaxPercent: function() {
        var netPrice = parseFloat(this.priceNetField.getValue());
        var tax      = parseFloat(this.priceTaxField.getValue());
        
        var taxPercent = tax / netPrice * 100;

        var roundedPercent = Math.round(Math.abs(taxPercent) * 100) / 100;

        this.salesTaxField.setValue(roundedPercent);
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     * 
     * @return {Object}
     * @private
     */
    getFormItems: function() {
        var formFieldDefaults = {
            xtype: 'textfield',
            anchor: '100%',
            labelSeparator: '',
            columnWidth: .5
        };
        
        this.dateOfInvoiceField = Ext.create({
            xtype: 'datefield',
            name: 'date',
            fieldLabel: this.app.i18n._('Date of invoice'),
            columnWidth: 1/4,
            allowBlank: false,
            listeners: {
                scope: this,
                blur: this.onUpdateDateOfInvoice.createDelegate(this)
            }
        });
        
        this.dueInDaysField = Ext.create({
            fieldLabel: this.app.i18n._('Due in'),
            columnWidth: 1/4,
            name: 'due_in',
            allowBlank: false,
            xtype: 'uxspinner',
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                alternateIncrementValue: 10,
                minValue: 0,
                maxValue: 1024,
                allowDecimals: false
            }),
            listeners: {
                scope: this,
                blur: this.onUpdateInDays.createDelegate(this)
            }
        });
        
        this.dueAtField = Ext.create({
            xtype: 'datefield',
            name: 'due_at',
            allowBlank: false,
            fieldLabel: this.app.i18n._('Due date'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.onUpdateDueAt.createDelegate(this)
            }
        });
        
        this.priceNetField = new Ext.ux.form.NumberField({
            name: 'price_net',
            xtype: 'numberfield',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            decimalPrecision: 2,
            suffix: ' €',
            fieldLabel: this.app.i18n._('Price Net'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.onUpdatePriceNet.createDelegate(this)
            }
        });
        
        this.priceGrossField = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_gross',
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Price Gross'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.calcGross.createDelegate(this)
            }
        });

        this.priceGross2Field = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_gross2',
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Additional Price Gross'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.calcTotal.createDelegate(this)
            }
        });

        this.priceTotalField = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_total',
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Total Price'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.calcTotal.createDelegate(this)
            }
        });
        
        this.priceTaxField = new Ext.ux.form.NumberField({
            decimalPrecision: 2,
            name: 'price_tax',
            xtype: 'numberfield',
            suffix: ' €',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Price Tax'),
            columnWidth: 1/4,
            listeners: {
                scope: this,
                blur: this.onUpdatePriceTax.createDelegate(this)
            }
        });
        
        this.salesTaxField = Ext.create({
            xtype: 'uxspinner',
            decimalPrecision: 2,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                alternateIncrementValue: 0.1,
                minValue: 0,
                maxValue: 100,
                allowDecimals: 2
            }),
            name: 'sales_tax',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Sales Tax (percent)'),
            columnWidth: 1/4,
            regex: /^[0-9]+\.?[0-9]*$/,
            listeners: {
                scope: this,
                spin: this.onUpdateSalesTax.createDelegate(this),
                blur: this.onUpdateSalesTax.createDelegate(this)
            }
        });
        
        this.discountField = Ext.create({
            xtype: 'uxspinner',
            decimalPrecision: 2,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                minValue: 0,
                maxValue: 100,
                allowDecimals: 0
            }),
            name: 'discount',
            decimalSeparator: Tine.Tinebase.registry.get('decimalSeparator'),
            fieldLabel: this.app.i18n._('Discount (%)'),
            columnWidth: 1/4,
            value: 0,
            regex: /^[0-9]+\.?[0-9]*$/,
            listeners: {
                scope: this,
                spin: this.calcTotal.createDelegate(this),
                blur: this.calcTotal.createDelegate(this)
            }
        });
        
        var items = [{
            title: this.app.i18n._('Purchase Invoice'),
            autoScroll: true,
            border: false,
            frame: true,
            layout: 'border',
            items: [{
                region: 'center',
                layout: 'hfit',
                border: false,
                items: [{
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Invoice'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [{
                                name: 'number',
                                fieldLabel: this.app.i18n._('Invoice Number'),
                                columnWidth: 1/4,
                                allowBlank: false
                                //readOnly: ! Tine.Tinebase.common.hasRight('set_invoice_number', 'Sales'),
                                //emptyText: this.app.i18n._('automatically set...')
                            }, {
                                fieldLabel: this.app.i18n._('Supplier'),
                                columnWidth: 3/4,
                                editDialog: this,
                                xtype: 'tinerelationpickercombo',
                                allowBlank: false,
                                app: 'Sales',
                                recordClass: Tine.Sales.Model.Supplier,
                                relationType: 'SUPPLIER',
                                relationDegree: 'sibling',
                                modelUnique: true,
                                ref: '../../../../../../../supplierPicker',
                                //readOnly: true,
                                name: 'supplier'
                            }], [
                                this.dateOfInvoiceField,
                                this.dueInDaysField,
                                this.dueAtField
                                /*{
                                    xtype: 'extuxclearabledatefield',
                                    name: 'overdue_at',
                                    fieldLabel: this.app.i18n._('Overdue date'),
                                    columnWidth: 1/4
                                    //emptyText: (this.record.get('is_auto') == 1) ? this.app.i18n._('automatically set...') : ''
                            }*/], [
                                this.priceNetField,
                                this.salesTaxField,
                                this.priceTaxField,
                                this.priceGrossField
                            ], [
                                this.priceGross2Field,
                                this.discountField,
                                {
                                    xtype: 'extuxclearabledatefield',
                                    name: 'discount_until',
                                    //allowBlank: false,
                                    fieldLabel: this.app.i18n._('Discount until'),
                                    columnWidth: 1/4
                                    //emptyText: (this.record.get('is_auto') == 1) ? this.app.i18n._('automatically set...') : ''
                                }
                            ], [
                                this.priceTotalField
                            ]
                        ]
                    }]
                }, {
                    xtype: 'fieldset',
                    layout: 'hfit',
                    autoHeight: true,
                    title: this.app.i18n._('Miscellaneous'),
                    items: [{
                        xtype: 'columnform',
                        labelAlign: 'top',
                        formDefaults: formFieldDefaults,
                        items: [
                            [
                                {
                                    xtype: 'extuxclearabledatefield',
                                    name: 'dunned_at',
                                    fieldLabel: this.app.i18n._('Dun date'),
                                    columnWidth: 1/4
                                }, {
                                    xtype: 'extuxclearabledatefield',
                                    name: 'payed_at',
                                    //allowBlank: false,
                                    fieldLabel: this.app.i18n._('Payed at'),
                                    columnWidth: 1/4
                                    //emptyText: (this.record.get('is_auto') == 1) ? this.app.i18n._('automatically set...') : ''
                                },
                                // is_payed
                                new Tine.Tinebase.widgets.keyfield.ComboBox({
                                    app: 'Sales',
                                    keyFieldName: 'paymentMethods',
                                    fieldLabel: this.app.i18n._('Method of payment'),
                                    name: 'payment_method',
                                    columnWidth: 1/4
                                })
                            ], [
                                {
                                    columnWidth: 2/4,
                                    editDialog: this,
                                    xtype: 'tinerelationpickercombo',
                                    fieldLabel: this.app.i18n._('Approver'),
                                    allowBlank: true,
                                    app: 'Addressbook',
                                    recordClass: Tine.Addressbook.Model.Contact,
                                    relationType: 'APPROVER',
                                    relationDegree: 'sibling',
                                    modelUnique: true
                                }, {
                                    columnWidth: 1/4,
                                    editDialog: this,
                                    xtype: 'tinerelationpickercombo',
                                    fieldLabel: this.app.i18n._('Lead Cost Center'),
                                    allowBlank: true,
                                    app: 'Sales',
                                    recordClass: Tine.Sales.Model.CostCenter,
                                    relationType: 'COST_CENTER',
                                    relationDegree: 'sibling',
                                    modelUnique: true
                                }
                                /*new Tine.Tinebase.widgets.keyfield.ComboBox({
                                    app: 'Sales',
                                    keyFieldName: 'invoiceCleared',
                                    fieldLabel: this.app.i18n._('Cleared'),
                                    name: 'cleared',
                                    allowBlank: false,
                                    columnWidth: 1/3
                                })*/
                            ]
                        ]
                    }]
                }]
            }, {
                // activities and tags
                layout: 'ux.multiaccordion',
                animate: true,
                region: 'east',
                width: 210,
                split: true,
                collapsible: true,
                collapseMode: 'mini',
                header: false,
                margins: '0 5 0 5',
                border: true,
                items: [
                    new Ext.Panel({
                        title: this.app.i18n._('Description'),
                        iconCls: 'descriptionIcon',
                        layout: 'form',
                        labelAlign: 'top',
                        border: false,
                        items: [{
                            style: 'margin-top: -4px; border 0px;',
                            labelSeparator: '',
                            xtype: 'textarea',
                            name: 'description',
                            hideLabel: true,
                            grow: false,
                            preventScrollbars: false,
                            anchor: '100% 100%',
                            emptyText: this.app.i18n._('Enter description'),
                            requiredGrant: 'editGrant'
                        }]
                    }),
                    new Tine.widgets.tags.TagPanel({
                        app: 'Sales',
                        border: false,
                        bodyStyle: 'border:1px solid #B5B8C8;'
                    })
                ]
            }]
        }];
        
        items.push(new Tine.widgets.activities.ActivitiesTabPanel({
            app:           this.appName,
            record_id:     this.record.id,
            record_model: 'Sales_Model_PurchaseInvoice'
        }));
        
        return {
            xtype:     'tabpanel',
            defaults: {
                hideMode: 'offsets'
            },
            border:    false,
            plain:     true,
            activeTab: 0,
            items:     items
        };
    }
});


/***/ }),

/***/ 768:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * InvoicePosition grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.InvoicePositionGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>InvoicePosition Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.InvoicePositionGridPanel
 */
Tine.Sales.InvoicePositionGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    storeRemoteSort: false,
    defaultSortInfo: {field: 'month', direction: 'ASC'},
    usePagingToolbar: false,
    frame: false,
    layout: 'fit',
    border: true,
    anchor: '100% 100%',
    editDialogRecordProperty: 'positions',
    
    /**
     * holds the php model name of the accountable
     * 
     * @type string
     */
    accountable: null,
    
    accountableApplication: null,
    
    groupField: null,
    
    invoiceId: null,
    
    i18nModelsName: null,
    i18nUnitName: null,
    unitName: null,
    renderedSum: null,
    renderedSumsPerMonth: null,
    
    initComponent: function() {
        this.bbar = [];
        
        Tine.Sales.InvoicePositionGridPanel.superclass.initComponent.call(this);
        
        this.fillBottomToolbar();
        
        this.grid.renderedSumsPerMonth = this.renderedSumsPerMonth;
        this.grid.view.renderedSumsPerMonth = this.renderedSumsPerMonth;
        
        if (this.groupField) {
            this.doGroup();
        }
    },
    
    /**
     * creates the view
     * 
     * @return {Object}
     */
    createView: function() {
        var view = Tine.Sales.InvoicePositionGridPanel.superclass.createView.call(this);
        view.renderedSumsPerMonth = this.renderedSumsPerMonth;
        return view;
    },
    
    doGroup: function() {
        if (! this.rendered) {
            this.doGroup.defer(200, this);
            return false;
        }
        
        this.store.sort(this.defaultSortInfo);
        this.store.groupBy(this.groupField);
    },
    
    /**
     * the export handler
     */
    onExport: function() {
        var downloader = new Ext.ux.file.Download({
            params: {
                method: 'Sales.exportInvoicePositions',
                requestType: 'HTTP',
                invoiceId: this.invoiceId,
                accountable: this.accountable
            }
        }).start();
    },
    
    initActions: function() {
        this.action_export = new Ext.Action({
            requiredGrant: 'addGrant',
            actionType: 'export',
            text: String.format(i18n._('Export Records from these Positions') + ' ({0})', this.i18nModelsName),
            handler: this.onExport.createDelegate(this),
            iconCls: 'action_export',
            scope: this
        });
    },
    
    /**
     * will be called in Edit Dialog Mode
     */
    fillBottomToolbar: function() {
        var bbar = this.getBottomToolbar();
        bbar.addButton(new Ext.Button(this.action_export));
        bbar.addItem('->');
        bbar.addItem({xtype: 'tbtext', text: this.i18nModelsName + ' (' + this.i18nUnitName + '): ' + '<b>' + this.renderedSum + '</b>'});
        bbar.addItem({xtype: 'tbspacer', width: 20});
    }
});


/***/ }),

/***/ 769:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * InvoicePosition panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.InvoicePositionPanel
 * @extends     Ext.Panel
 * 
 * <p>InvoicePosition Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.InvoiceGridPanel
 */
Tine.Sales.InvoicePositionPanel = Ext.extend(Ext.Panel, {
    /**
     * holds positions from the edit dialog records positions property
     * 
     * @type array
     */
    positions: null,
    
    /**
     * holds the id of the invoice
     * 
     * @type string
     */
    invoiceId: null,
    
    positionsPerAccountable: null,
    
    app: null,
    
    autoScroll: true,
    
    /**
     * holds all accountables needed
     * 
     * @type {Array}
     */
    accountables: null,
    /**
     * 
     * @type {Array}
     */
    modelsOfAccountable: null,
    sumsPerAccountable: null,
    
    initComponent: function(deferred) {
        
        // defer this, otherwise renderers won't have been registered, yet.
        if (! deferred) {
            this.initComponent.defer(150, this, [true]);
            return false;
        }

        this.accountables = [];
        this.positionsPerAccountable = {};
        this.sumsPerAccountable = {};
        this.modelsOfAccountable = [];
        
        Tine.Sales.InvoicePositionPanel.superclass.initComponent.call(this);
        
        this.initStoreAndPanels();
    },
    
    /**
     * creates a store containing all positions
     */
    initStoreAndPanels: function() {
        // interrupt process flow until we got the positions from the editdialog set
        if (! this.positions) {
            this.initStoreAndPanels.defer(50, this);
            return;
        }
        
        if (! Ext.isArray(this.positions)) {
            Tine.log.error('No Invoice Positions given:');
            Tine.log.error(this.positions);
            return;
        }
        
        for (var index = 0; index < this.positions.length; index++) {
            var key = this.positions[index].model + this.positions[index].unit;
            var key = key.replace(/\s/g, "");
            if (this.accountables.indexOf(key) == -1) {
                this.accountables.push(key);
                this.modelsOfAccountable[key] = this.positions[index].model;
                this.positionsPerAccountable[key] = [];
                this.sumsPerAccountable[key] = 0.0;
            }
            
            this.positionsPerAccountable[key].push(this.positions[index]);
            this.sumsPerAccountable[key] += parseFloat(this.positions[index].quantity);
        }
        
        // prepeare rendered sums registry
        Tine.Sales.renderedSumsPerMonth[this.invoiceId] = {};
        
        // not needed anymore
        this.positions = null;
        
        for (var index = 0; index < this.accountables.length; index++) {
            
            var mypositions = this.positionsPerAccountable[this.accountables[index]];
            
            var pseudoRecord     = new Tine.Sales.Model.Invoice({
                positions: mypositions,
                id: this.invoiceId
            });
            
            // find out months of the accountable type to decide if grouping is required
            var mymonths = [];
            var mysumspermonth = {};
            for (var index2 = 0; index2 < mypositions.length; index2++) {
                if (! mysumspermonth['month-' + mypositions[index2].month]) {
                    mysumspermonth['month-' + mypositions[index2].month] = 0.0;
                }
                
                mysumspermonth['month-' + mypositions[index2].month] += parseFloat(mypositions[index2].quantity);
                
                if (mymonths.indexOf(mypositions[index2].month) == -1) {
                    mymonths.push(mypositions[index2].month);
                }
            }
            var pseudoRecord2 = {data: {unit: mypositions[0]['unit'], model: this.modelsOfAccountable[this.accountables[index]]}};
            var renderedSumsPerMonth = {};
            
            Ext.iterate(mysumspermonth, function(month, sum) {
                renderedSumsPerMonth[month] = Tine.Sales.renderInvoicePositionQuantity(mysumspermonth[month], null, pseudoRecord2);
            });
            
            Tine.Sales.renderedSumsPerMonth[this.invoiceId][this.accountables[index]] = renderedSumsPerMonth;
            
            var pseudoEditDialog = {record: pseudoRecord, app: this.app};
            
            var split = this.modelsOfAccountable[this.accountables[index]].split('_Model_');
            if (Tine[split[0]]) {
                var model = Tine[split[0]].Model[split[1]];
                var accountableApplication = Tine.Tinebase.appMgr.get(split[0]);
                var renderedSum = Tine.Sales.renderInvoicePositionQuantity(this.sumsPerAccountable[this.accountables[index]], null, pseudoRecord2);
                var grid = new Tine.Sales.InvoicePositionGridPanel({
                    collapsible: true,
                    collapsed: true,
                    editDialog: pseudoEditDialog,
                    height: (mymonths.length > 1) ? 350 : 250, // if grid will be grouped, make it bigger
                    title: accountableApplication.i18n._(model.getRecordsName()) +
                    ' (' + mypositions.length + ')' + ' - ' +
                    accountableApplication.i18n._(mypositions[0]['unit']) + ': ' + renderedSum,
                    app: this.app,
                    i18nModelsName: accountableApplication.i18n._(model.getRecordsName()),
                    i18nUnitName: accountableApplication.i18n._(mypositions[0]['unit']),
                    accountable: this.modelsOfAccountable[this.accountables[index]],
                    accountableApplication: accountableApplication,
                    invoiceId: this.invoiceId,
                    renderedSum: renderedSum,
                    renderedSumsPerMonth: renderedSumsPerMonth,
                    unitName: mypositions[0]['unit'],
                    groupField: (mymonths.length > 1) ? 'month' : null
                });

                this.add(grid);
            } else {
                Tine.log.warn('Application for accountable ' + this.accountables[index] + ' not found!');
            }
        }
    }
});


/***/ }),

/***/ 770:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Invoice grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.InvoiceGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Invoice Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.InvoiceGridPanel
 */
Tine.Sales.InvoiceGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    
    initComponent: function() {
        this.initDetailsPanel();
        Tine.Sales.InvoiceGridPanel.superclass.initComponent.call(this);
    },
    
    /**
     * is called when the component is rendered
     * @param {} ct
     * @param {} position
     */
    onRender : function(ct, position) {
        this.billMask = new Ext.LoadMask(ct, {msg: this.app.i18n._('Rebilling Invoice...')});
        Tine.Sales.ContractGridPanel.superclass.onRender.call(this, ct, position);
    },
    
    /**
     * @todo: make this generally available (here its more general: Tine.HumanResources.EmployeeGridPanel)
     * 
     * returns additional toobar items
     * 
     * @return {Array} of Ext.Action
     */
    getActionToolbarItems: function() {
        this.actions_reversal = new Ext.Action({
            text: this.app.i18n._('Create Reversal Invoice'),
            iconCls: 'action_reversal',
            scope: this,
            disabled: true,
            allowMultiple: false,
            handler: this.onReverseInvoice,
            actionUpdater: function(action, grants, records) {
                if (records.length == 1 && records[0].get('type') == 'INVOICE' && records[0].get('number')) {
                    action.enable();
                } else {
                    action.disable();
                }
            }
        });

        var reversalButton = Ext.apply(new Ext.Button(this.actions_reversal), {
            scale: 'medium',
            rowspan: 2,
            iconAlign: 'top'
        });
        
        this.actions_rebill = new Ext.Action({
            text: this.app.i18n._('Rebill Invoice'),
            iconCls: 'action_rebill',
            scope: this,
            disabled: true,
            allowMultiple: false,
            handler: this.onRebillInvoice,
            actionUpdater: function(action, grants, records) {
                if (records.length == 1 && records[0].get('type') == 'INVOICE' && records[0].get('cleared') != 'CLEARED'  && records[0].get('is_auto')) {
                    action.enable();
                } else {
                    action.disable();
                }
            }
        });

        var rebillButton = Ext.apply(new Ext.Button(this.actions_rebill), {
            scale: 'medium',
            rowspan: 2,
            iconAlign: 'top'
        });
        
        this.actions_merge = new Ext.Action({
            text: this.app.i18n._('Merge Invoices'),
            iconCls: 'action_merge',
            scope: this,
            disabled: true,
            allowMultiple: false,
            handler: this.onMergeInvoice,
            actionUpdater: function(action, grants, records) {
                if (records.length == 1 && records[0].get('type') == 'INVOICE' && records[0].get('cleared') != 'CLEARED') {
                    action.enable();
                } else {
                    action.disable();
                }
            }
        });

        var mergeButton = Ext.apply(new Ext.Button(this.actions_merge), {
            scale: 'medium',
            rowspan: 2,
            iconAlign: 'top'
        });
        
        var additionalActions = [this.actions_reversal, this.actions_rebill, this.actions_merge];
        this.actionUpdater.addActions(additionalActions);
        return [reversalButton, rebillButton, mergeButton];
    },
    
    /**
     * is called on reversal invoice action
     * 
     * @param {Ext.Action} action
     * @param {Object} event
     */
    onReverseInvoice: function(action, event) {
        var rows = this.getGrid().getSelectionModel().getSelections();
        if (rows.length == 1) {
            var record = rows[0];
            
            var cfg = {
                record: record,
                createReversal: true
            };
            
            Tine.Sales.InvoiceEditDialog.openWindow(cfg);
        }
    },
    
    /**
     * 
     */
    onRebillInvoice: function() {
        var rows = this.getGrid().getSelectionModel().getSelections();
        
        if (rows.length != 1) {
            return;
        }
        
        this.billMask.show();
        
        var that = this;
        
        var req = Ext.Ajax.request({
            url : 'index.php',
            params : { 
                method: 'Sales.rebillInvoice', 
                id:     rows[0].id 
            },
            success : function(result, request) {
                that.billMask.hide();
                that.getGrid().store.reload();
            },
            failure : function(exception) {
                that.billMask.hide();
                Tine.Tinebase.ExceptionHandler.handleRequestException(exception);
            },
            scope: that
        });
    },
    
    onMergeInvoice: function(action, event) {
        var rows = this.getGrid().getSelectionModel().getSelections();
        
        if (rows.length != 1) {
            return;
        }
        
        this.billMask.show();
        
        var that = this;
        
        var req = Ext.Ajax.request({
            url : 'index.php',
            params : { 
                method: 'Sales.mergeInvoice', 
                id:     rows[0].id 
            },
            success : function(result, request) {
                that.billMask.hide();
                that.getGrid().store.reload();
            },
            failure : function(exception) {
                that.billMask.hide();
                Tine.Tinebase.ExceptionHandler.handleRequestException(exception);
            },
            scope: that
        });
    },
    
    /**
     * add custom items to context menu
     * 
     * @return {Array}
     */
    getContextMenuItems: function() {
        var items = [
            '-',
            this.actions_reversal,
            this.actions_rebill,
            this.actions_merge
            ];
        
        return items;
    },
    
    /**
     * @private
     */
    initDetailsPanel: function() {
        this.detailsPanel = new Tine.Sales.InvoiceDetailsPanel({
            grid: this,
            app: this.app
        });
    }
});


/***/ }),

/***/ 771:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * Invoice grid panel
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.PurchaseInvoiceGridPanel
 * @extends     Tine.widgets.grid.GridPanel
 * 
 * <p>Invoice Grid Panel</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>    
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.PurchaseInvoiceGridPanel
 */
Tine.Sales.PurchaseInvoiceGridPanel = Ext.extend(Tine.widgets.grid.GridPanel, {
    
    initComponent: function() {
        this.initDetailsPanel();
        Tine.Sales.PurchaseInvoiceGridPanel.superclass.initComponent.call(this);
    },

    /**
     * @private
     */
    initDetailsPanel: function() {
        this.detailsPanel = new Tine.Sales.PurchaseInvoiceDetailsPanel({
            grid: this,
            app:  this.app
        });
    }
});


/***/ }),

/***/ 772:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * Address selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.AddressSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.AddressSearchCombo
 */
Tine.Sales.AddressSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    itemSelector: 'div.search-item',
    minListWidth: 200,
    sortBy: 'locality',
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.Address;
        this.recordProxy = Tine.Sales.addressBackend;
        this.initTemplate();
        Tine.Sales.AddressSearchCombo.superclass.initComponent.call(this);
    },
    
    /**
     * init template
     * @private
     */
    initTemplate: function() {
        if (! this.tpl) {
            this.tpl = new Ext.XTemplate(
                '<tpl for="."><div class="search-item">',
                    '<table cellspacing="0" cellpadding="2" border="0" style="font-size: 11px;" width="100%">',
                        '<tr>',
                            '<td style="height:16px">{[this.encode(values)]}</td>',
                        '</tr>',
                    '</table>',
                '</div></tpl>',
                {
                    encode: function(values) { return Ext.util.Format.htmlEncode(values.fulltext) }
                }
            );
        }
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'Address', Tine.Sales.AddressSearchCombo);


/***/ }),

/***/ 773:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * Sales combo box and store
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */

Ext.ns('Tine.Sales');

/**
 * OrderConfirmation selection combo box
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.OrderConfirmationSearchCombo
 * @extends     Ext.form.ComboBox
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Michael Spahn <kontakt@michaelspahn.de>
 * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.OrderConfirmationSearchCombo
 */
Tine.Sales.OrderConfirmationSearchCombo = Ext.extend(Tine.Tinebase.widgets.form.RecordPickerComboBox, {
    
    allowBlank: false,
    minListWidth: 200,
    
    //private
    initComponent: function(){
        this.recordClass = Tine.Sales.Model.OrderConfirmation;
        this.recordProxy = Tine.Sales.orderconfirmationBackend;

        Tine.Sales.OrderConfirmationSearchCombo.superclass.initComponent.call(this);

        this.displayField = 'fulltext';
        this.sortBy = 'number';
    }
});

Tine.widgets.form.RecordPickerManager.register('Sales', 'OrderConfirmation', Tine.Sales.OrderConfirmationSearchCombo);


/***/ }),

/***/ 774:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.InvoiceDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 * 
 * <p>Invoice details Panel</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.InvoiceDetailsPanel
 */
Tine.Sales.InvoiceDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
    
    defaultHeight: 145,
    
    /**
     * init
     */
    initComponent: function() {

        // init templates
        this.initTemplate();
        this.initDefaultTemplate();
        
        Tine.Sales.InvoiceDetailsPanel.superclass.initComponent.call(this);
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Sales.InvoiceDetailsPanel.superclass.afterRender.apply(this, arguments);
    },
    
    /**
     * init default template
     * 
     * @todo: generalize this
     */
    initDefaultTemplate: function() {
        
        this.defaultTpl = new Ext.XTemplate(
            '<div class="preview-panel-timesheet-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-invoice-default">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n.n_hidden('Invoice', 'Invoices', 3) + '</div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            this.app.i18n._('Select invoice') + '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
            '</div>'
        );
    },
    
    /**
     * init single contact template (this.tpl)
     */
    initTemplate: function() {
        var that = this;
        this.tpl = new Ext.XTemplate(
            '<tpl for=".">',
                '<!-- Preview core data -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Invoice') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Invoice Number') + '</span>{[this.encode(values, "number")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Date') + '</span>{[this.encode(values, "date")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Type') + '</span>{[this.encode(values, "type")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Description') + '</span>{[this.encode(values, "description")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Customer') + '</span>{[this.encode(values, "customer")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contract') + '</span>{[this.encode(values, "contract")]}<br/>',
                    '</div>',
                '</div>',

                '<!-- Preview accounting data -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Billing Address') + '</div>',
                    '<div>',
                        '{[this.encode(values, "address")]}<br/>',
                    '</div>',
                '</div>',
            
                '<!-- Preview description -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Miscellaneous') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Credit Term') + '</span>{[this.encode(values, "credit_term")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n.n_('Cost Center', 'Cost Centers', 1) + '</span>{[this.encode(values, "costcenter_id")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Cleared') + '</span>{[this.encode(values, "cleared")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Price Net') + '</span>{[this.encode(values, "price_net")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Price Tax') + ' (' + '{[this.encode(values, "sales_tax")]}' + ')' + '</span>{[this.encode(values, "price_tax")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Price Gross') + '</span>{[this.encode(values, "price_gross")]}<br/>',
                    '</div>',
                '</div>',
            '</tpl>',
            {
                /**
                 * encode
                 */
                encode: function(value, key) {
                    switch (key) {
                        case 'address':
                            if (value.fixed_address) {
                                return Ext.util.Format.nl2br(value.fixed_address);
                            } else if (value.address_id) {
                                var address = new Tine.Sales.Model.Address(value.address_id);
                                return Ext.util.Format.nl2br(Tine.Sales.renderAddress(address));
                            } else {
                                return '';
                            }
                        case 'contract':
                        case 'customer':
                            var renderer = Tine.widgets.grid.RendererManager.get('Sales', 'Invoice', key);
                            return renderer(that.record.get('relations'));
                        case 'price_gross':
                            return Ext.util.Format.money(value.price_gross);
                        case 'price_net':
                            return Ext.util.Format.money(value.price_net);
                        case 'price_tax':
                            return Ext.util.Format.money(value.price_tax);
                    }

                    var renderer = Tine.widgets.grid.RendererManager.get('Sales', 'Invoice', key);
                    if (renderer) {
                        return renderer(value[key], key, that.record);
                    } else {
                        return '';
                    }
                }
            }
        );
    }
});


/***/ }),

/***/ 775:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.PurchaseInvoiceDetailsPanel
 * @extends     Tine.widgets.grid.DetailsPanel
 * 
 * <p>Invoice details Panel</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.PurchaseInvoiceDetailsPanel
 */
Tine.Sales.PurchaseInvoiceDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
    
    defaultHeight: 145,
    
    /**
     * init
     */
    initComponent: function() {

        // init templates
        this.initTemplate();
        this.initDefaultTemplate();
        
        Tine.Sales.PurchaseInvoiceDetailsPanel.superclass.initComponent.call(this);
    },

    /**
     * add on click event after render
     */
    afterRender: function() {
        Tine.Sales.PurchaseInvoiceDetailsPanel.superclass.afterRender.apply(this, arguments);
    },
    
    /**
     * init default template
     * 
     * @todo: generalize this
     */
    initDefaultTemplate: function() {
        
        this.defaultTpl = new Ext.XTemplate(
            '<div class="preview-panel-timesheet-nobreak">',    
                '<!-- Preview contacts -->',
                '<div class="preview-panel preview-panel-invoice-default">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n.n_hidden('Invoice', 'Invoices', 3) + '</div>',
                    '<div class="preview-panel-timesheet-leftside preview-panel-left">',
                        '<span class="preview-panel-bold">',
                            this.app.i18n._('Select invoice') + '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                    '<div class="preview-panel-timesheet-rightside preview-panel-left">',
                        '<span class="preview-panel-nonbold">',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                            '<br/>',
                        '</span>',
                    '</div>',
                '</div>',
            '</div>'
        );
    },
    
    /**
     * init single contact template (this.tpl)
     */
    initTemplate: function() {
        var that = this;
        this.tpl = new Ext.XTemplate(
            '<tpl for=".">',
                '<!-- Preview core data -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Invoice') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Invoice Number') + '</span>{[this.encode(values, "number")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Date') + '</span>{[this.encode(values, "date")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Type') + '</span>{[this.encode(values, "type")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Description') + '</span>{[this.encode(values, "description")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Customer') + '</span>{[this.encode(values, "customer")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Contract') + '</span>{[this.encode(values, "contract")]}<br/>',
                    '</div>',
                '</div>',

                '<!-- Preview accounting data -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Billing Address') + '</div>',
                    '<div>',
                        '{[this.encode(values, "address")]}<br/>',
                    '</div>',
                '</div>',
            
                '<!-- Preview description -->',
                '<div class="preview-panel preview-panel-invoice-left preview-panel-customer">',
                    '<div class="bordercorner_1"></div>',
                    '<div class="bordercorner_2"></div>',
                    '<div class="bordercorner_3"></div>',
                    '<div class="bordercorner_4"></div>',
                    '<div class="preview-panel-declaration">' + this.app.i18n._('Miscellaneous') + '</div>',
                    '<div class="preview-panel-left">',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Credit Term') + '</span>{[this.encode(values, "credit_term")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n.n_('Cost Center', 'Cost Centers', 1) + '</span>{[this.encode(values, "costcenter_id")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Cleared') + '</span>{[this.encode(values, "cleared")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Price Net') + '</span>{[this.encode(values, "price_net")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Price Tax') + ' (' + '{[this.encode(values, "sales_tax")]}' + ')' + '</span>{[this.encode(values, "price_tax")]}<br/>',
                        '<span class="preview-panel-symbolcompare wide">' + this.app.i18n._('Total Price') + '</span>{[this.encode(values, "price_total")]}<br/>',
                    '</div>',
                '</div>',
            '</tpl>',
            {
                /**
                 * encode
                 */
                encode: function(value, key) {
                    switch (key) {
                        case 'address':
                            if (value.fixed_address) {
                                return Ext.util.Format.nl2br(value.fixed_address);
                            } else if (value.address_id) {
                                var address = new Tine.Sales.Model.Address(value.address_id);
                                return Ext.util.Format.nl2br(Tine.Sales.renderAddress(address));
                            } else {
                                return '';
                            }
                        case 'contract':
                        case 'customer':
                            var renderer = Tine.widgets.grid.RendererManager.get('Sales', 'Invoice', key);
                            return renderer(that.record.get('relations'));
                        case 'price_total':
                            return Ext.util.Format.money(value.price_total);
                        case 'price_net':
                            return Ext.util.Format.money(value.price_net);
                        case 'price_tax':
                            return Ext.util.Format.money(value.price_tax);
                    }

                    var renderer = Tine.widgets.grid.RendererManager.get('Sales', 'Invoice', key);
                    if (renderer) {
                        return renderer(value[key], key, that.record);
                    } else {
                        return '';
                    }
                }
            }
        );
    }
});


/***/ }),

/***/ 776:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.OrderConfirmationFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.OrderConfirmationFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'order_confirmation',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Order Confirmation');
        this.foreignRecordClass = Tine.Sales.Model.OrderConfirmation;
        this.pickerConfig = {emptyText: this.app.i18n._('without order confirmation'), allowBlank: true};
        Tine.Sales.CustomerFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.offer-order_confirmation']  = Tine.Sales.OrderConfirmationFilterModel;

/***/ }),

/***/ 777:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
Ext.namespace('Tine.Sales');

/**
 * Billing Date Dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.BillingDateDialog
 * @extends     Ext.FormPanel
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @constructor
 * @param {Object} config The configuration options.
 */

Tine.Sales.BillingDateDialog = Ext.extend(Ext.FormPanel, {
    
    // private
    layout : 'fit',
    border : false,
    cls : 'tw-editdialog',
    labelAlign : 'top',
    anchor : '100% 100%',
    deferredRender : false,
    buttonAlign : null,
    bufferResize : 500,
    
    /**
     * the calling application
     * 
     * @type Tine.Tinebase.Application
     */
    app: null,
    
    initComponent: function() {
        
        this.app = Tine.Tinebase.appMgr.get('Sales');
        
        this.initActions();
        this.initButtons();
        this.initFormItems();
        
        Tine.Sales.BillingDateDialog.superclass.initComponent.call(this);
        
        this.getForm().findField('billing_date').focus(true, 200);
    },
    
    /**
     * create the buttons
     */
    initButtons : function() {
        this.fbar = [ '->', this.action_cancel, this.action_update];
    },
    
    /**
     * populates this.items with the form items
     */
    initFormItems: function() {
        this.items = {
            title: null,
            border: false,
            frame: true,
            layout: 'border',
            cls: 'x-window-dlg',
            items: [{
                title: null,
                region: 'center',
                xtype: 'columnform',
                labelAlign: 'top',
                items: [[{
                    fieldLabel: this.panelDialog,
                    xtype: 'datefield',
                    name: 'billing_date',
                    anchor: '100%',
                    columnWidth: 1,
                    allowBlank: false,
                    value: new Date()
                }]]
            }]
        };
    },
    
    /**
     * is called on render, creates keymap
     * @param {} ct
     * @param {} position
     */
    onRender : function(ct, position) {
        Tine.Sales.BillingDateDialog.superclass.onRender.call(this, ct, position);

        // generalized keybord map for edit dlgs
        new Ext.KeyMap(ct, [ {
            key : [ 10, 13 ], // ctrl + return
            ctrl : true,
            fn : this.onOk,
            scope : this
        }]);
    },
    
    /**
     * called on clicking the OK button
     */
    onOk: function() {
        this.window.fireEvent('submit', this.getForm().findField('billing_date').getValue(), this.contractId);
        this.window.close();
    },
    
    /**
     * close window
     */
    onCancel: function() {
        this.window.close();
    },
    
    /**
     * initializes the actions
     */
    initActions: function() {
        this.action_cancel = new Ext.Action({
            text: i18n._('Cancel'),
            minWidth: 70,
            scope: this,
            handler: this.onCancel,
            iconCls: 'action_cancel'
        });
        
        this.action_update = new Ext.Action({
            text : i18n._('Ok'),
            minWidth : 70,
            scope : this,
            handler: this.onOk,
            iconCls : 'action_saveAndClose'
        });
    }
});


/**
 * @param {Object}
 * 
 * @return {Ext.ux.Window}
 */
Tine.Sales.BillingDateDialog.openWindow = function(config) {
    var window = Tine.WindowFactory.getExtWindow({
        title: config.winTitle,
        width : 350,
        height : 150,
        contentPanelConstructor : 'Tine.Sales.BillingDateDialog',
        contentPanelConstructorConfig : config
    });
    
    window.addEvents('submit');
    
    return window;
};

/***/ }),

/***/ 778:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 *
 */
 
Ext.namespace('Tine.Sales');

/**
 * Offer edit dialog
 * 
 * @namespace   Tine.Sales
 * @class       Tine.Sales.OfferEditDialog
 * @extends     Tine.widgets.dialog.EditDialog
 * 
 * <p>Offer Edit Dialog</p>
 * <p><pre>
 * </pre></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013-2014 Metaways Infosystems GmbH (http://www.metaways.de)
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.OfferGridPanel
 */
Tine.Sales.OfferEditDialog = Ext.extend(Tine.widgets.dialog.EditDialog, {
    
    windowWidth: 650,
    windowHeight: 350,

    displayNotes: true,
    
    
    /**
     * init component
     */
    initComponent: function () {
        Tine.Sales.OfferEditDialog.superclass.initComponent.call(this);
    },
    
    /**
     * @see: Tine.widgets.dialog.EditDialog.onRecordLoad
     */
    onRecordLoad: function() {
        Tine.Sales.OfferEditDialog.superclass.onRecordLoad.call(this);
        
        if (! this.copyRecord && ! this.record.id) {
            this.window.setTitle(this.app.i18n._('Add New Offer'));
        }
    },
    
    /**
     * called on multiple edit
     * @return {Boolean}
     */
    isMultipleValid: function() {
        return true;
    },
    
    /**
     * returns dialog
     * 
     * NOTE: when this method gets called, all initalisation is done.
     */
    getFormItems: function() {
        return {
            xtype: 'tabpanel',
            border: false,
            plain:true,
            activeTab: 0,
            border: false,
            defaults: {
                hideMode: 'offsets'
            },
            plugins: [{
                ptype : 'ux.tabpanelkeyplugin'
            }],
            items:[
                {
                title: this.app.i18n.n_('Offer', 'Offers', 1),
                autoScroll: true,
                border: false,
                frame: true,
                layout: 'border',
                items: [{
                    region: 'center',
                    xtype: 'columnform',
                    labelAlign: 'top',
                    formDefaults: {
                        xtype:'textfield',
                        anchor: '100%',
                        labelSeparator: '',
                        columnWidth: 1/2
                    },
                    items: [[{
                        fieldLabel: this.app.i18n._('Number'),
                        name: 'number',
                        disabled: false,
                        allowBlank: true // autoset if empty
                    },{
                        fieldLabel: this.app.i18n._('Title'),
                        name: 'title',
                        allowBlank: false
                    }], [{
                            xtype: 'tinerelationpickercombo',
                            fieldLabel: this.app.i18n._('Customer'),
                            editDialog: this,
                            allowBlank: false,
                            app: 'Sales',
                            recordClass: Tine.Sales.Model.Customer,
                            relationType: 'OFFER',
                            relationDegree: 'sibling',
                            modelUnique: true,
                            columnWidth: 1
                        }]
                    ]
                }, {
                    // activities and tags
                    layout: 'ux.multiaccordion',
                    animate: true,
                    region: 'east',
                    width: 210,
                    split: true,
                    collapsible: true,
                    collapseMode: 'mini',
                    header: false,
                    margins: '0 5 0 5',
                    border: true,
                    items: [
                        new Ext.Panel({
                            title: this.app.i18n._('Description'),
                            iconCls: 'descriptionIcon',
                            layout: 'form',
                            labelAlign: 'top',
                            border: false,
                            items: [{
                                style: 'margin-top: -4px; border 0px;',
                                labelSeparator: '',
                                xtype: 'textarea',
                                name: 'description',
                                hideLabel: true,
                                grow: false,
                                preventScrollbars: false,
                                anchor: '100% 100%',
                                emptyText: this.app.i18n._('Enter description'),
                                requiredGrant: 'editGrant'
                            }]
                        }),
                        new Tine.widgets.tags.TagPanel({
                            app: 'Sales',
                            border: false,
                            bodyStyle: 'border:1px solid #B5B8C8;'
                        })
                    ]
                }]
            }, new Tine.widgets.activities.ActivitiesTabPanel({
                app: this.appName,
                record_id: this.record.id,
                record_model: 'Sales_Model_Offer'
            })]
        };
    }
});


/***/ }),

/***/ 779:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractCustomerFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.ContractCustomerFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'customer',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Customer');
        this.foreignRecordClass = Tine.Sales.Model.Customer;
        this.pickerConfig = {emptyText: this.app.i18n._('without customer'), allowBlank: true};

        Tine.Sales.ContractCustomerFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.contractcustomer'] = Tine.Sales.ContractCustomerFilterModel;


/***/ }),

/***/ 780:
/***/ (function(module, exports) {

/**
 * Tine 2.0
 * 
 * @package     Sales
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
 */
 
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ContractContactInternalFilterModel
 * @extends     Tine.widgets.grid.ForeignRecordFilter
 * 
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 */
Tine.Sales.PurchaseInvoiceApproverFilterModel = Ext.extend(Tine.widgets.grid.ForeignRecordFilter, {
    
    // private
    field: 'approver',
    valueType: 'relation',
    
    /**
     * @private
     */
    initComponent: function() {
        this.app = Tine.Tinebase.appMgr.get('Sales');
        this.label = this.app.i18n._('Approver');
        this.foreignRecordClass = Tine.Addressbook.Model.Contact;
        this.pickerConfig = {emptyText: this.app.i18n._('without approver'), allowBlank: true};

        Tine.Sales.PurchaseInvoiceApproverFilterModel.superclass.initComponent.call(this);
    }
});

Tine.widgets.grid.FilterToolbar.FILTERS['sales.purchaseinvoice_approver'] = Tine.Sales.PurchaseInvoiceApproverFilterModel;


/***/ }),

/***/ 781:
/***/ (function(module, exports) {

/*
 * Tine 2.0
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * @copyright   Copyright (c) 2014-2017 Metaways Infosystems GmbH (http://www.metaways.de)
 */
Ext.ns('Tine.Sales');

/**
 * @namespace   Tine.Sales
 * @class       Tine.Sales.ProductAggregateGridPanel
 * @extends     Tine.widgets.grid.PickerGridPanel
 * 
 * <p>Product aggregate grid panel</p>
 * <p></p>
 * 
 * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
 * @author      Alexander Stintzing <a.stintzing@metaways.de>
 * 
 * @param       {Object} config
 * @constructor
 * Create a new Tine.Sales.ProductAggregateGridPanel
 */
Tine.Sales.ProductAggregateGridPanel = Ext.extend(Tine.widgets.grid.QuickaddGridPanel, {
    /*
     * config
     */
    frame: true,
    border: true,
    autoScroll: true,
    layout: 'fit',
    defaultSortInfo: {field: 'product_id', direction: 'DESC'},
    quickaddMandatory: 'product_id',
    clicksToEdit: 1,
    enableColumnHide:false,
    enableColumnMove:false,
    enableHdMenu: false,
    recordClass: 'Sales.ProductAggregate',
    validate: true,

    /*
     * public
     */
    app: null,
    
    /**
     * the calling editDialog
     * Tine.Sales.ContractEditDialog
     */
    editDialog: null,
    
    /**
     * initializes the component
     */
    initComponent: function() {
        this.title = this.i18nTitle = this.app.i18n.ngettext('Product', 'Products', 2),
        
        Tine.Sales.ProductAggregateGridPanel.superclass.initComponent.call(this);
        this.store.sortInfo = this.defaultSortInfo;
        
        
        
        this.on('afteredit', this.onAfterEdit, this);
        this.editDialog.on('load', this.loadRecord, this);
        
        // custom sort for product_id
        this.store.sortData = (function(f, direction) {
            if (f !== 'product_id') {
                Ext.data.Store.prototype.sortData.call(this.store, f, direction);
            } else {
                direction = direction || 'ASC';
                var fn = function(r1, r2) {
                    var v1 = r1.data.product_id.description,
                        v2 = r2.data.product_id.description;
                    
                    return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
                };
                
                this.store.data.sort(direction, fn);
            }
        }).createDelegate(this);
        
        this.store.sort();
        
        this.on('beforeedit', this.onBeforeRowEdit, this);
        
        // sync record on these events
        this.store.on('update', this.syncStoreToRecord.createDelegate(this));
        this.store.on('add', this.syncStoreToRecord.createDelegate(this));
        this.store.on('remove', this.syncStoreToRecord.createDelegate(this));
    },
    
    /**
     * 
     * @param {} store
     * @param {} record
     * @param {} operation
     */
    syncStoreToRecord: function(store, record, operation) {
        if (this.editDialog.record) {
            var items = [];
            store.each(function(item) {
                if (! item.data.last_autobill) {
                    item.data.last_autobill = null;
                }
                items.push(item.data);
            });
            this.editDialog.record.set('products', items);
            
            this.updateTitle(items.length);
        }
    },
    
    /**
     * updates the title of the tab by adding the number of containing records in braces
     * 
     * @param {Number} count
     */
    updateTitle: function(count) {
        count = Ext.isNumber(count) ? count : this.store.getCount();
        this.setTitle(this.i18nTitle + ' (' + count + ')');
    },
    
    /**
     * loads the existing ProductAggregates into the store
     */
    loadRecord: function() {
        var c = this.editDialog.record.get('products');
        if (Ext.isArray(c)) {
            Ext.each(c, function(ar) {
                this.store.addSorted(new this.recordClass(ar));
            }, this);
        }
    },
    
    /**
     * new entry event -> add new record to store
     * @see Tine.widgets.grid.QuickaddGridPanel
     * @param {Object} recordData
     * @return {Boolean}
     */
    onNewentry: function(recordData) {
        recordData.contract_id = this.editDialog.record.get('id');
        var relatedRecord = this.productQuickadd.store.getById(this.productQuickadd.getValue());
        recordData.product_id = relatedRecord.data;
        Tine.Sales.ProductAggregateGridPanel.superclass.onNewentry.call(this, recordData);  
    },
    
    /**
     * returns column model
     * 
     * @return Ext.grid.ColumnModel
     * @private
     */
    getColumnModel: function() {
        this.productEditor = Tine.widgets.form.RecordPickerManager.get('Sales', 'Product', { allowBlank: true});
        
        this.quantityEditor = new Ext.ux.form.Spinner({
            fieldLabel: this.app.i18n._('Quantity'),
            name: 'quantity',
            allowBlank: true,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                minValue: 1,
                maxValue: 9999999,
                allowDecimals: false
            })
        });

        
        this.intervalEditor = new Ext.ux.form.Spinner({
            fieldLabel: this.app.i18n._('Interval'),
            name: 'interval',
            allowBlank: false,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                minValue: 1,
                maxValue: 36,
                allowDecimals: false
            })
        });
        
        this.productQuickadd = Tine.widgets.form.RecordPickerManager.get('Sales', 'Product', {allowBlank: true});
        this.quantityQuickadd = new Ext.ux.form.Spinner({
            fieldLabel: this.app.i18n._('Quantity'),
            name: 'quantity',
            allowBlank: true,
            value: null,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                minValue: 1,
                maxValue: 9999,
                allowDecimals: false
            })
        });
        this.intervalQuickadd = new Ext.ux.form.Spinner({
            fieldLabel: this.app.i18n._('Interval'),
            name: 'interval',
            allowBlank: false,
            value: 1,
            strategy: new Ext.ux.form.Spinner.NumberStrategy({
                incrementValue : 1,
                minValue: 1,
                maxValue: 36,
                allowDecimals: false
            })
        });
        
        var cmp = {
            name: 'billing_point',
            fieldLabel: this.app.i18n._('Billing Point'),
            xtype: 'combo',
            value: 'begin',
            store: [
                ['begin', this.app.i18n._('begin') ],
                [  'end', this.app.i18n._('end') ]
            ]
        };
        
        this.billingPointEditor = new Ext.form.ComboBox(cmp);
        this.billingPointQuickadd = new Ext.form.ComboBox(cmp);
        
        var columns = [
            {id: 'product_id', dataIndex: 'product_id', type: Tine.Sales.Model.ProductAggregate, header: this.app.i18n._('Product'),
                 quickaddField: this.productQuickadd, renderer: this.renderProductAggregate,
                 editor: this.productEditor, scope: this, width: 270
            },
            {id: 'quantity', editor: this.quantityEditor, renderer: this.renderQuantity, quickaddField: this.quantityQuickadd, dataIndex: 'quantity', header: this.app.i18n._('Quantity'),  scope: this, width: 54},
            {id: 'interval', editor: this.intervalEditor, quickaddField: this.intervalQuickadd, dataIndex: 'interval', header: this.app.i18n._('Interval'),  scope: this, width: 60},
            {id: 'billing_point', renderer: this.renderBillingPoint , editor: this.billingPointEditor, quickaddField: this.billingPointQuickadd, dataIndex: 'billing_point', header: this.app.i18n._('Billing Point'),  scope: this, width: 140},
            {id: 'start_date', renderer: Tine.Tinebase.common.dateRenderer, editor: new Ext.ux.form.ClearableDateField(), quickaddField: new Ext.ux.form.ClearableDateField(), dataIndex: 'start_date', header: this.app.i18n._('Start Date'),  scope: this, width: 110},
            {id: 'end_date', renderer: Tine.Tinebase.common.dateRenderer, editor: new Ext.ux.form.ClearableDateField(), quickaddField: new Ext.ux.form.ClearableDateField(), dataIndex: 'end_date', header: this.app.i18n._('End Date'),  scope: this, width: 110},
            {id: 'last_autobill', renderer: Tine.Tinebase.common.dateRenderer, editor: new Ext.ux.form.ClearableDateField(), hidden: true, dataIndex: 'last_autobill', header: this.app.i18n._('Last Autobill'),  scope: this, width: 110},
            {id: 'creation_time',      header: i18n._('Creation Time'),         dataIndex: 'creation_time',         renderer: Tine.Tinebase.common.dateRenderer,        hidden: true, sortable: true },
            {id: 'created_by',         header: i18n._('Created By'),            dataIndex: 'created_by',            renderer: Tine.Tinebase.common.usernameRenderer,    hidden: true, sortable: true },
            {id: 'last_modified_time', header: i18n._('Last Modified Time'),    dataIndex: 'last_modified_time',    renderer: Tine.Tinebase.common.dateRenderer,        hidden: true, sortable: true },
            {id: 'last_modified_by',   header: i18n._('Last Modified By'),      dataIndex: 'last_modified_by',      renderer: Tine.Tinebase.common.usernameRenderer,    hidden: true, sortable: true }
        ];

        return new Ext.grid.ColumnModel({
            defaults: {
                sortable: true,
                width: 160,
                editable: true
            }, 
            columns: columns
       });
    },
    
    /**
     * renders the billing point
     * 
     * @param {String} value
     * @return {String}
     */
    renderBillingPoint: function(value) {
        if (value == 'end') {
            return this.app.i18n._('end');
        } else {
            return this.app.i18n._('begin');
        }
    },
    
    renderQuantity: function(value, cell, record) {
        // product does not bill an accountable -> return qty
        var ac = record.get('product_id').accountable;
        if (! ac || ac == 'Sales_Model_ProductAggregate' || ac == 'Sales_Model_Product') {
            return value;
        }
        
        return '';
    },
    
    /**
     * is called on after edit to set related records
     * @param {} o
     */
    onAfterEdit: function(o) {  
        switch (o.field) {
            case 'quantity':
                o.record.set('quantity', o.value);
                break;
            case 'product_id':
                var relatedRecord = this.productEditor.store.getById(o.value);
                o.record.set('product_id', relatedRecord.data);
                break;
            case 'interval':
                o.record.set('interval', o.value);
                break;
            case 'billing_point':
                var val = o.value;
                if (Ext.isEmpty(val)) {
                    val = 'begin';
                }
                o.record.set('billing_point', val);
                break;
            default: // do nothing
        }
    },
    
    /**
     * creates the special editors
     * @param {} o
     */
    onBeforeRowEdit: function(o) {
        if (o.field == 'quantity') {
            // product does not bill an accountable -> return qty
            var ac = o.record.get('product_id').accountable;

            if (!(! ac || ac == 'Sales_Model_ProductAggregate' || ac == 'Sales_Model_Product')) {
                return false; 
            } else {
                return true;
            }
        }
        
        return;
    },
    
    /**
     * renders the cost center
     * @param {Object} value
     * @param {Object} row
     * @param {Tine.Tinebase.data.Record} record
     * 
     * return {String}
     */
    renderProductAggregate: function(value, row, record) {
        return '<span class="tine-recordclass-gridicon SalesProduct">&nbsp;</span>' + (record ? record.getTitle() : '');
    },

    /**
     * @private
     */
    initActions: function() {
        Tine.Sales.ProductAggregateGridPanel.superclass.initActions.call(this);

        // TODO prevent multiselect and change of records without defined attributes
        this.editAttributesAction = new Ext.Action({
            text: this.app.i18n._('Edit Attributes'),
            iconCls: 'actionEdit',
            handler : this.onEditAttributes,
            scope: this
        });
    },

    /**
     * edit attributes: open modal window with key/value grid
     */
    onEditAttributes: function() {
        var selectedRows = this.getSelectionModel().getSelections(),
            selectedRecord = selectedRows[0],
            attributeKeys = this.getAttributeKeysFromAccountable(selectedRecord);

        if (attributeKeys.length == 0) {
            // no attribute keys -> return
            return;
        }

        this.initAttributesCombos(attributeKeys);
        var cols = [
            {
                id: 'id',
                // TODO pass this.app.i18n
                header: i18n._('Attribute'),
                dataIndex: 'id',
                hideable: false,
                sortable: false,
                editor: this.attributeEditor,
                quickaddField: this.attributesQuickadd
            }, {
                id: 'value',
                header: i18n._('Value'),
                dataIndex: 'value',
                hideable: false,
                sortable: false,
                editor: new Ext.form.TextField({}),
                quickaddField: new Ext.form.TextField({
                    emptyText: i18n._('Add a New Value...')
                })
            }
        ];

        this.attributesGrid = new Tine.Tinebase.widgets.keyfield.ConfigGrid({
            hasDefaultCheck: false,
            cols: cols
        });
        this.loadAttributesFromRecord(selectedRecord, attributeKeys);

        this.attributesWindow = Tine.WindowFactory.getWindow({
            modal: true,
            width: 500,
            height: 320,
            border: false,
            // maybe we should create a common ancestor for ConfigGrid and json attributes grid
            items: this.attributesGrid,
            fbar: ['->', {
                text: i18n._('Cancel'),
                minWidth: 70,
                scope: this,
                handler: this.onAttributesWindowClose,
                iconCls: 'action_cancel'
            }, {
                text: i18n._('OK'),
                minWidth: 70,
                scope: this,
                handler: this.onAttributesWindowOK,
                iconCls: 'action_applyChanges'
            }]
        });
    },

    initAttributesCombos: function(attributeKeys) {
        var storeData = [];
        Ext.each(attributeKeys, function(key) {
            // TODO add translation?
            storeData.push([key, key]);
        });
        var cmp = {
            name: 'attributes',
            fieldLabel: this.app.i18n._('Attribute'),
            xtype: 'combo',
            value: 'vcpus',
            store: storeData
        };

        this.attributeEditor = new Ext.form.ComboBox(cmp);
        this.attributesQuickadd = new Ext.form.ComboBox(cmp);
    },

    getAttributeKeysFromAccountable: function(record) {
        var accountable = record.get('product_id').accountable;

        if (accountable == 'WebAccounting_Model_ProxmoxVM') {
            // TODO get accountable keys from modelconfig / registry (Tine.WebAccounting.registry.get('models')[MODEL])
            return ['vcpus', 'memory', 'storage'];
        } else {
            return [];
        }
    },

    /**
     * load data from prod agg record into grid store
     */
    loadAttributesFromRecord: function(record, attributeKeys)
    {
        var attributes = record.get('json_attributes'),
            value = {'records': []};

        Ext.each(attributeKeys, function(key) {
            if (attributes && attributes[key]) {
                value.records.push({
                    id: key,
                    value: attributes[key]
                });
            }
        });
        this.attributesGrid.setValue(value);
    },

    /**
     * put data from grid into prod agg record
     */
    onAttributesWindowOK: function () {
        var selectedRows = this.getSelectionModel().getSelections(),
            selectedRecord = selectedRows[0],
            records = this.attributesGrid.getValue().records,
            attributes = {};

        Ext.each(records, function(attribute) {
            attributes[attribute.id] = attribute.value;
        }, this);

        selectedRecord.set('json_attributes', attributes);
        selectedRecord.commit();

        this.onAttributesWindowClose();
    },

    /**
     * Close store Window
     */
    onAttributesWindowClose: function () {
        this.attributesWindow.purgeListeners();
        this.attributesWindow.close();
    },

    getContextMenuItems: function() {
        return [this.editAttributesAction];
    }
});


/***/ }),

/***/ 782:
/***/ (function(module, exports, __webpack_require__) {

// style-loader: Adds some css to the DOM by adding a <style> tag

// load the styles
var content = __webpack_require__(783);
if(typeof content === 'string') content = [[module.i, content, '']];
// Prepare cssTransformation
var transform;

var options = {"hmr":true}
options.transform = transform
// add the styles to the DOM
var update = __webpack_require__(1)(content, options);
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
	// When the styles change, update the <style> tags
	if(!content.locals) {
		module.hot.accept("!!../../Tinebase/js/node_modules/css-loader/index.js!./Sales.css", function() {
			var newContent = require("!!../../Tinebase/js/node_modules/css-loader/index.js!./Sales.css");
			if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
			update(newContent);
		});
	}
	// When the module is disposed, remove the <style> tags
	module.hot.dispose(function() { update(); });
}

/***/ }),

/***/ 783:
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(0)(undefined);
// imports


// module
exports.push([module.i, "/**\n * Tine 2.0\n * \n * @package     Sales\n * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3\n * @author      Philipp Schüle <p.schuele@metaways.de>\n * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)\n *\n */\n\n.SalesIconCls {\n    background-image:url(" + __webpack_require__(167) + ") !important;\n}\n\n.x-tree-node-icon.SalesContract, .SalesContract {\n    background-image:url(" + __webpack_require__(784) + ") !important;\n}\n\n.x-tree-node-icon.SalesProduct, .SalesProduct, .x-tree-node-icon.SalesProductAggregate, .SalesProductAggregate {\n    background-image:url(" + __webpack_require__(785) + ") !important;\n}\n\n\n.SalesCostCenter {\n    background-image:url(" + __webpack_require__(167) + ") !important;\n}\n\n.SalesCustomer {\n    background-image:url(" + __webpack_require__(95) + ") !important;\n}\n\n.SalesSupplier {\n    background-image:url(" + __webpack_require__(786) + ") !important;\n}\n\n.SalesAddress {\n    background-image:url(" + __webpack_require__(787) + ") !important;\n}\n\n.SalesInvoice {\n    background-image:url(" + __webpack_require__(168) + ") !important;\n}\n\n.SalesPurchaseInvoice {\n    background-image:url(" + __webpack_require__(788) + ") !important;\n}\n\n.SalesDivision {\n    background-image:url(" + __webpack_require__(789) + ") !important;\n}\n\n.action_reversal {\n    background-image:url(" + __webpack_require__(790) + ") !important;\n}\n\n.action_rebill {\n    background-image:url(" + __webpack_require__(791) + ") !important;\n}\n\n.action_merge {\n    background-image:url(" + __webpack_require__(792) + ") !important;\n}\n\n.action_bill {\n    background-image:url(" + __webpack_require__(168) + ") !important;\n}\n\n.preview-panel-symbolcompare.wide {width: 160px}\n.preview-panel-customer { margin: 5px 2px 5px 5px; width: 32%; min-width: 200px}\n.preview-panel-description.preview-panel-customer {width: 22%; min-width: 200px}\n\n.clipboard {\n    background-image:url(" + __webpack_require__(793) + ") !important;\n}\n\n.preview-panel-invoice-default {\n    display: block;\n    height: 122px;\n    padding: 5px;\n    margin: 5px;\n    font-family: verdana;\n}\n\n.preview-panel-invoice-left {\n    float: left;\n    position: relative;\n    width: 32%;\n    height: 122px;\n    padding: 5px;\n    margin: 5px 2px 5px 5px;\n    font-family: verdana;\n    font-size: 10px;\n    color: #404040;\n}\n\n.SalesOrderConfirmation {\n    background-image:url(" + __webpack_require__(794) + ") !important;\n}\n\n.SalesOffer {\n    background-image:url(" + __webpack_require__(795) + ") !important;\n}", ""]);

// exports


/***/ }),

/***/ 784:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M14.8,32c0.1,0.3,0.5,0.4,0.7,0.6c0.3,0.1,0.6-0.1,0.8-0.2c1.3-0.6,3.1,0.1,4.5,0.1c0.8,0,0.8-1.3,0-1.3 c-1.6,0-3-0.4-4.6-0.1c0-0.1,0-0.2-0.1-0.4c-0.3-0.5-0.7-0.7-1.1-0.6c0-0.1,0-0.1-0.1-0.2c-0.1-0.2-0.2-0.2-0.4-0.3 c0.5-0.8,0.7-1.6,0.4-2.3c-0.1-0.2-0.3-0.3-0.6-0.3c-0.9,0-1.6,0.9-2.1,1.4c-1.4,1.3-2.6,2.9-3.8,4.4c-0.5,0.7,0.6,1.3,1.1,0.6 c1-1.4,2.1-2.7,3.3-3.9c-0.3,0.5-0.6,0.9-0.9,1.4c-0.5,0.7,0.6,1.3,1.1,0.6c0.1-0.2,0.3-0.3,0.4-0.4c0,0.1-0.1,0.2-0.1,0.2 c0,0,0,0,0,0c0,0.1-0.1,0.1-0.1,0.1c-0.3,0.7,0.8,1,1.2,0.5c0.1-0.1,0.2-0.3,0.3-0.4C14.8,31.7,14.8,31.9,14.8,32L14.8,32z M27.9,35.6H3.6V6.4h14.6v7.9c0,0.5,0.2,0.9,0.5,1.3c0.4,0.4,0.8,0.5,1.3,0.5h7.9v2h2.4v-3.8c0-0.5-0.1-1.1-0.4-1.7 c-0.3-0.6-0.6-1.1-0.9-1.4l-5.9-5.9c-0.4-0.4-0.8-0.7-1.4-0.9C21.1,4.1,20.5,4,20,4H3C2.5,4,2.1,4.2,1.7,4.5 C1.4,4.9,1.2,5.3,1.2,5.8v30.4c0,0.5,0.2,0.9,0.5,1.3S2.5,38,3,38h25.5c0.5,0,0.9-0.2,1.3-0.5s0.5-0.8,0.5-1.3V33h-2.4V35.6z M20.6,6.6C21,6.7,21.3,6.8,21.4,7l5.9,5.9c0.2,0.2,0.3,0.4,0.4,0.8h-7.1V6.6z M22.9,17.7c0.1,0.1,0.2,0.3,0.2,0.4v1.2 c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H9.1c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4 c0.1-0.1,0.3-0.2,0.4-0.2h13.4C22.6,17.6,22.8,17.6,22.9,17.7z M22.9,22.6c0.1,0.1,0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4 c-0.1,0.1-0.3,0.2-0.4,0.2H9.1c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4V23c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2 h13.4C22.6,22.4,22.8,22.5,22.9,22.6z M26.8,29.9l2-1.8l-2.3-2.6l-2,1.8l0,0.9l1.6,0.1l-0.1,1.6L26.8,29.9z M34.5,18.7 c-0.2-0.2-0.3-0.2-0.5,0L28,24c-0.2,0.2-0.2,0.4,0,0.5c0.2,0.2,0.3,0.2,0.5,0l6-5.4C34.7,19,34.7,18.8,34.5,18.7z M34.4,16.3 l4.4,4.9L27.4,31.5l-4.7-0.2l0.2-4.7L34.4,16.3z M41.4,18.8l-1.6,1.4l-4.4-4.9l1.6-1.4c0.3-0.3,0.7-0.4,1.1-0.4 c0.4,0,0.8,0.2,1.1,0.5l2.3,2.6c0.3,0.3,0.4,0.7,0.4,1.1C41.9,18.2,41.8,18.5,41.4,18.8z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 785:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M35.4,16.2c0-0.4-0.1-0.8-0.3-1.1l-5.3-9.4C29.2,4.6,28,4,26.7,4H14.7c-1.3,0-2.5,0.6-3.1,1.7l-5.3,9.4 C6.1,15.4,6,15.8,6,16.2l0,19.9c0,1,1,1.8,2.1,1.8h25.2c1.2,0,2.1-0.8,2.1-1.8L35.4,16.2z M27.4,6.7l4.6,8.1h-9.9V6.3h4.6 C27,6.3,27.2,6.4,27.4,6.7L27.4,6.7z M14.1,6.7c0.1-0.2,0.4-0.4,0.7-0.4h4.6v8.5H9.5L14.1,6.7z M32.7,35.6H8.7V17.1h24.1V35.6z M32.7,35.6 M12.8,21.7c0,1,0.9,1.7,2,1.7h11.9c1.1,0,2-0.8,2-1.7c0-1-0.9-1.7-2-1.7H14.8C13.7,19.9,12.8,20.7,12.8,21.7L12.8,21.7z M12.8,21.7'/%3E %3C/svg%3E\""

/***/ }),

/***/ 786:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cg%3E %3Cg%3E %3Cpath d='M36.3,27.1c-0.3-0.7-1.1-1.2-1.8-0.9l-7.2,2.6c-1.2-1.8-3.3-2.8-5.5-2.5L15.2,9.1c-0.2-0.6-0.7-0.9-1.3-0.9H6.5 C5.7,8.2,5,8.8,5,9.6c0,0.8,0.7,1.5,1.5,1.5H13l6.2,16.2c-1.9,1.3-3,3.6-2.5,6c0.6,3.2,3.7,5.3,6.9,4.6c3-0.6,5.1-3.4,4.7-6.4 l7.1-2.5C36.1,28.6,36.6,27.8,36.3,27.1L36.3,27.1z M23,35.1c-1.6,0.3-3.3-0.8-3.6-2.4c-0.3-1.6,0.8-3.3,2.4-3.6 c1.6-0.3,3.2,0.7,3.6,2.4C25.8,33.2,24.7,34.8,23,35.1L23,35.1z M23,35.1'/%3E %3Cpath d='M24.7,24.4c0.3,0.7,1,1.2,1.8,0.8l6.6-2.5c0.7-0.2,1.1-1,0.8-1.8l-6.2-16c-0.3-0.7-1.1-1.1-1.8-0.8l-6.7,2.5 c-0.7,0.2-1.1,1-0.8,1.8L24.7,24.4z M25.6,7.2l5.1,13.4l-4,1.5L21.6,8.7L25.6,7.2z M25.6,7.2'/%3E %3C/g%3E %3C/g%3E %3C/svg%3E\""

/***/ }),

/***/ 787:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M20.9,25.5c0,0.8-0.2,1.4-0.7,2s-1,0.8-1.7,0.8H9.1c-0.7,0-1.2-0.3-1.7-0.8s-0.7-1.2-0.7-2c0-0.8,0.1-1.5,0.2-2.2 s0.3-1.3,0.5-1.9c0.3-0.6,0.6-1.1,1.1-1.4c0.5-0.4,1.1-0.5,1.8-0.5c0.1,0,0.3,0.2,0.6,0.3s0.5,0.3,0.7,0.4c0.2,0.1,0.4,0.2,0.7,0.3 c0.3,0.1,0.5,0.2,0.8,0.3c0.3,0.1,0.5,0.1,0.8,0.1c0.3,0,0.5,0,0.8-0.1c0.3-0.1,0.5-0.1,0.8-0.3c0.3-0.1,0.5-0.2,0.7-0.3 c0.2-0.1,0.4-0.2,0.7-0.4c0.3-0.2,0.5-0.3,0.6-0.3c0.7,0,1.3,0.2,1.8,0.5c0.5,0.4,0.9,0.8,1.1,1.4c0.3,0.6,0.4,1.2,0.5,1.9 C20.8,24,20.9,24.7,20.9,25.5z M18,15.9c0,1.2-0.4,2.1-1.2,3c-0.8,0.8-1.8,1.2-3,1.2s-2.1-0.4-3-1.2s-1.2-1.8-1.2-3s0.4-2.1,1.2-3 c0.8-0.8,1.8-1.2,3-1.2s2.1,0.4,3,1.2C17.6,13.8,18,14.8,18,15.9z M35.1,24.1v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2 H23.9c-0.2,0-0.3-0.1-0.4-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h10.6 c0.2,0,0.3,0.1,0.4,0.2C35,23.8,35.1,24,35.1,24.1z M35.1,19.5v1c0,0.2-0.1,0.3-0.2,0.5c-0.1,0.1-0.3,0.2-0.5,0.2H23.9 c-0.2,0-0.3-0.1-0.5-0.2s-0.2-0.3-0.2-0.5v-1c0-0.2,0.1-0.3,0.2-0.5s0.3-0.2,0.5-0.2h10.5c0.2,0,0.3,0.1,0.5,0.2 C35,19.1,35.1,19.3,35.1,19.5z M35.1,14.7v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H23.9c-0.2,0-0.3-0.1-0.4-0.2 c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h10.6c0.2,0,0.3,0.1,0.4,0.2S35.1,14.5,35.1,14.7z M37.4,32.4V10c0-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.3-0.2-0.4-0.2H5c-0.2,0-0.3,0.1-0.4,0.2C4.4,9.7,4.4,9.8,4.4,10v22.4 c0,0.2,0.1,0.3,0.2,0.4C4.7,32.9,4.8,33,5,33h6.5v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 c0.1,0.1,0.2,0.3,0.2,0.4V33H28v-1.8c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h1.2c0.2,0,0.3,0.1,0.4,0.2 c0.1,0.1,0.2,0.3,0.2,0.4V33h6.5c0.2,0,0.3-0.1,0.4-0.2C37.4,32.7,37.4,32.6,37.4,32.4z M39.8,10v22.4c0,0.8-0.3,1.5-0.9,2.1 c-0.6,0.6-1.3,0.9-2.1,0.9H5c-0.8,0-1.5-0.3-2.1-0.9C2.3,33.9,2,33.2,2,32.4V10c0-0.8,0.3-1.5,0.9-2.1S4.1,7,5,7h31.9 c0.8,0,1.5,0.3,2.1,0.9C39.5,8.4,39.8,9.1,39.8,10z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 788:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M32,24.9c0.1,0.1,0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H18.2c-0.2,0-0.3-0.1-0.4-0.2 c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h13.4C31.7,24.7,31.9,24.8,32,24.9z M31.6,29.6H18.2 c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4v1.2c0,0.2,0.1,0.3,0.2,0.4C17.9,32,18,32,18.2,32h13.4c0.2,0,0.3-0.1,0.4-0.2 c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C31.9,29.6,31.7,29.6,31.6,29.6z M25.5,18.8c0.1-0.2,0.2-0.3,0.2-0.5 c0-0.3-0.2-0.6-0.5-0.7c-0.2-0.1-0.4-0.2-0.5-0.2c-0.3,0-0.7,0.2-0.8,0.6l0,0c-0.5,1.2-1.7,2-2.8,2c-0.9,0-1.7-0.4-2.3-1.1h2 c0.2,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.4,0.3-0.7c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2.8c0-0.2-0.1-0.4-0.1-0.7 c0-0.2,0-0.4,0.1-0.6h2.8c0.2,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.4,0.3-0.7c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2 c0.6-0.8,1.4-1.2,2.4-1.2c1.1,0,2.2,0.7,2.8,2l0,0.1l0,0c0.2,0.2,0.5,0.4,0.8,0.4c0.1,0,0.2,0,0.4-0.1l0.1,0l0.1-0.1 c0.2-0.2,0.4-0.5,0.4-0.8c0-0.1,0-0.2-0.1-0.4l0,0l0,0c-0.8-1.9-2.6-3.1-4.4-3.1c-2.1,0-3.8,1.3-4.6,3.2h-1c-0.2,0-0.5,0.1-0.7,0.3 c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.2,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3H16c0,0.1,0,0.3,0,0.4c0,0.3,0,0.5,0.1,0.8h-0.6 c-0.2,0-0.5,0.1-0.7,0.3c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.2,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3h1.2c0.9,1.7,2.5,2.9,4.4,2.9 C22.9,21.6,24.6,20.5,25.5,18.8L25.5,18.8C25.4,18.9,25.4,18.8,25.5,18.8C25.4,18.8,25.5,18.8,25.5,18.8L25.5,18.8z'/%3E %3Cg%3E %3Cpath d='M39.1,12.7c-0.3-0.6-0.6-1.1-0.9-1.4l-5.9-5.9c-0.4-0.4-0.8-0.7-1.4-0.9C30.2,4.1,29.6,4,29.1,4h-17 c-0.5,0-0.9,0.2-1.3,0.5c-0.4,0.4-0.5,0.8-0.5,1.3v9.7l2.4,2.4V6.4h14.6v7.9c0,0.5,0.2,0.9,0.5,1.3c0.4,0.4,0.8,0.5,1.3,0.5H37 v19.4H12.7v-9.6l-2.4,2.4v7.8c0,0.5,0.2,0.9,0.5,1.3c0.4,0.4,0.8,0.5,1.3,0.5h25.5c0.5,0,0.9-0.2,1.3-0.5c0.4-0.4,0.5-0.8,0.5-1.3 V14.3C39.5,13.8,39.3,13.3,39.1,12.7z M29.7,13.7V6.6c0.4,0.1,0.6,0.3,0.8,0.4l5.9,5.9c0.2,0.2,0.3,0.4,0.4,0.8H29.7z'/%3E %3C/g%3E %3Cpath d='M13.4,21.2L8.2,16c-0.2-0.2-0.4-0.3-0.7-0.3c-0.3,0-0.5,0.1-0.7,0.3l-0.6,0.6c-0.2,0.2-0.3,0.4-0.3,0.7s0.1,0.5,0.3,0.7 l2.3,2.3H2.9c-0.3,0-0.5,0.1-0.7,0.3C2.1,20.9,2,21.1,2,21.4v1c0,0.3,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3h5.6l-2.3,2.3 C6,26,5.9,26.2,5.9,26.5S6,27,6.2,27.2l0.6,0.6C7,28,7.2,28.1,7.5,28.1c0.3,0,0.5-0.1,0.7-0.3l5.2-5.2c0.2-0.2,0.3-0.4,0.3-0.7 C13.7,21.6,13.6,21.4,13.4,21.2z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 789:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cstyle type='text/css'%3E .st0%7Bfill:%23FFFFFF;%7D %3C/style%3E %3Cpath d='M33.5,23.3v10.6c0,0.4-0.1,0.7-0.4,1c-0.3,0.3-0.6,0.4-1,0.4h-8.5v-8.5H18v8.5H9.5c-0.4,0-0.7-0.1-1-0.4 c-0.3-0.3-0.4-0.6-0.4-1V23.3c0,0,0,0,0-0.1c0,0,0-0.1,0-0.1l12.7-10.5l12.7,10.5C33.5,23.2,33.5,23.3,33.5,23.3z M38.5,21.8 l-1.4,1.6c-0.1,0.1-0.3,0.2-0.5,0.2h-0.1c-0.2,0-0.3-0.1-0.5-0.2L20.8,10.8L5.5,23.5c-0.2,0.1-0.4,0.2-0.5,0.2 c-0.2,0-0.3-0.1-0.5-0.2l-1.4-1.6C3,21.7,3,21.5,3,21.3c0-0.2,0.1-0.4,0.2-0.5L19.1,7.6c0.5-0.4,1-0.6,1.7-0.6s1.2,0.2,1.7,0.6 l5.4,4.5l5.7,4.7l4.8,4c0.1,0.1,0.2,0.3,0.2,0.5S38.6,21.7,38.5,21.8z'/%3E %3Cpath class='st0' d='M29.6,32.1c0,1-0.3,1.8-0.9,2.4c-0.6,0.6-1.4,0.9-2.4,0.9H15.4c-1,0-1.8-0.3-2.4-0.9c-0.6-0.6-0.9-1.4-0.9-2.4 c0-0.5,0-0.9,0.1-1.3c0.1-0.5,0.1-0.9,0.2-1.4c0.1-0.5,0.2-0.9,0.3-1.3c0.1-0.4,0.3-0.8,0.5-1.2c0.2-0.4,0.5-0.7,0.8-1 c0.3-0.3,0.7-0.5,1.1-0.7c0.4-0.1,0.9-0.3,1.4-0.3c0.1,0,0.3,0.1,0.5,0.3s0.6,0.4,0.9,0.6c0.3,0.2,0.8,0.4,1.3,0.6s1.1,0.3,1.6,0.3 c0.5,0,1.1-0.1,1.6-0.3s1-0.4,1.3-0.6c0.3-0.2,0.7-0.4,0.9-0.6c0.3-0.2,0.5-0.3,0.5-0.3c0.5,0,1,0.1,1.4,0.3 c0.4,0.2,0.8,0.4,1.1,0.7c0.3,0.3,0.5,0.6,0.8,1c0.2,0.4,0.4,0.8,0.5,1.2c0.1,0.4,0.3,0.9,0.3,1.3c0.1,0.5,0.1,0.9,0.2,1.4 C29.6,31.3,29.6,31.7,29.6,32.1z M25,20.9c0,1.2-0.4,2.2-1.2,3c-0.9,0.9-1.8,1.2-3,1.2c-1.2,0-2.2-0.4-3-1.2c-0.9-0.9-1.2-1.8-1.2-3 s0.4-2.2,1.2-3c0.9-0.8,1.8-1.2,3-1.2c1.2,0,2.2,0.4,3,1.2C24.6,18.8,25,19.8,25,20.9z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 790:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M28,21.2c0-0.2,0.1-0.3,0.2-0.4l0.9-0.9c0.1-0.1,0.3-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2l3,3l3-3c0.1-0.1,0.3-0.2,0.4-0.2 c0.2,0,0.3,0.1,0.4,0.2l0.9,0.9c0.1,0.1,0.2,0.3,0.2,0.4c0,0.2-0.1,0.3-0.2,0.4l-3,3l3,3c0.1,0.1,0.2,0.3,0.2,0.4 c0,0.2-0.1,0.3-0.2,0.4l-0.9,0.9c-0.1,0.1-0.3,0.2-0.4,0.2c-0.2,0-0.3-0.1-0.4-0.2l-3-3l-3,3c-0.1,0.1-0.3,0.2-0.4,0.2 c-0.2,0-0.3-0.1-0.4-0.2l-0.9-0.9c-0.1-0.1-0.2-0.3-0.2-0.4c0-0.2,0.1-0.3,0.2-0.4l3-3l-3-3C28.1,21.5,28,21.4,28,21.2z M26.7,24.9 c0.1,0.1,0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.4,0.2H12.9c-0.2,0-0.3-0.1-0.4-0.2 c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.4-0.2h13.4C26.4,24.7,26.6,24.8,26.7,24.9z M26.3,29.6 H12.9c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4v1.2c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.3,0.2,0.4,0.2h13.4 c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C26.6,29.6,26.4,29.6,26.3,29.6z M31.7,31h2.4v5.2 c0,0.5-0.2,0.9-0.5,1.3c-0.4,0.4-0.8,0.5-1.3,0.5H6.8c-0.5,0-0.9-0.2-1.3-0.5C5.2,37.1,5,36.7,5,36.2V5.8c0-0.5,0.2-0.9,0.5-1.3 S6.3,4,6.8,4h17c0.5,0,1.1,0.1,1.7,0.4c0.6,0.3,1.1,0.6,1.4,0.9l5.9,5.9c0.4,0.4,0.7,0.8,0.9,1.4c0.3,0.6,0.4,1.2,0.4,1.7v5.2h-2.4 v-3.4h-7.9c-0.5,0-0.9-0.2-1.3-0.5S22,14.8,22,14.3V6.4H7.4v29.2h24.3V31z M24.4,13.7h7.1c-0.1-0.4-0.3-0.6-0.4-0.8L25.2,7 c-0.2-0.2-0.4-0.3-0.8-0.4V13.7z M20.2,18.8c0.1-0.2,0.2-0.3,0.2-0.5c0-0.3-0.2-0.6-0.5-0.7c-0.2-0.1-0.4-0.2-0.5-0.2 c-0.3,0-0.7,0.2-0.8,0.6l0,0c-0.5,1.2-1.7,2-2.8,2c-0.9,0-1.7-0.4-2.3-1.1h2c0.2,0,0.5-0.1,0.7-0.3c0.2-0.2,0.3-0.4,0.3-0.7 c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2.8c0-0.2-0.1-0.4-0.1-0.7c0-0.2,0-0.4,0.1-0.6h2.8c0.2,0,0.5-0.1,0.7-0.3 c0.2-0.2,0.3-0.4,0.3-0.7c0-0.2-0.1-0.5-0.3-0.7c-0.2-0.2-0.4-0.3-0.7-0.3h-2c0.6-0.8,1.4-1.2,2.4-1.2c1.1,0,2.2,0.7,2.8,2l0,0.1 l0,0c0.2,0.2,0.5,0.4,0.8,0.4c0.1,0,0.2,0,0.4-0.1l0.1,0l0.1-0.1c0.2-0.2,0.4-0.5,0.4-0.8c0-0.1,0-0.2-0.1-0.4l0,0l0,0 c-0.8-1.9-2.6-3.1-4.4-3.1c-2.1,0-3.8,1.3-4.6,3.2h-1c-0.2,0-0.5,0.1-0.7,0.3c-0.2,0.2-0.3,0.4-0.3,0.7c0,0.2,0.1,0.5,0.3,0.7 c0.2,0.2,0.4,0.3,0.7,0.3h0.6c0,0.1,0,0.3,0,0.4c0,0.3,0,0.5,0.1,0.8h-0.6c-0.2,0-0.5,0.1-0.7,0.3c-0.2,0.2-0.3,0.4-0.3,0.7 c0,0.2,0.1,0.5,0.3,0.7c0.2,0.2,0.4,0.3,0.7,0.3h1.2c0.9,1.7,2.5,2.9,4.4,2.9C17.6,21.6,19.3,20.5,20.2,18.8L20.2,18.8 C20.1,18.9,20.1,18.8,20.2,18.8C20.2,18.8,20.2,18.8,20.2,18.8L20.2,18.8z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 791:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M35.3,9.4v8.3c0,0.3-0.1,0.6-0.4,0.8c-0.2,0.2-0.5,0.4-0.8,0.4h-8.3c-0.5,0-0.9-0.2-1.1-0.7c-0.2-0.5-0.1-0.9,0.3-1.3 l2.5-2.5c-1.8-1.7-4-2.5-6.4-2.5c-1.3,0-2.5,0.2-3.7,0.7c-1.2,0.5-2.2,1.2-3,2c-0.8,0.8-1.5,1.9-2,3c-0.5,1.2-0.7,2.4-0.7,3.7 s0.2,2.5,0.7,3.7c0.5,1.2,1.2,2.2,2,3c0.8,0.8,1.9,1.5,3,2c1.2,0.5,2.4,0.7,3.7,0.7c1.5,0,2.8-0.3,4.1-1c1.3-0.6,2.4-1.5,3.3-2.7 c0.1-0.1,0.2-0.2,0.4-0.2c0.2,0,0.3,0.1,0.5,0.2l2.5,2.5c0.1,0.1,0.2,0.2,0.2,0.4s0,0.3-0.1,0.4c-1.3,1.6-3,2.9-4.9,3.8 c-1.9,0.9-3.9,1.3-6,1.3c-1.9,0-3.7-0.4-5.5-1.1s-3.3-1.8-4.5-3c-1.3-1.3-2.3-2.8-3-4.5S7,23.1,7,21.2s0.4-3.7,1.1-5.5 s1.8-3.3,3-4.5s2.8-2.3,4.5-3S19.2,7,21.2,7c1.8,0,3.6,0.3,5.2,1c1.7,0.7,3.2,1.6,4.5,2.9l2.4-2.4c0.4-0.4,0.8-0.5,1.3-0.3 C35.1,8.5,35.3,8.8,35.3,9.4z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 792:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath id='Pfeil_links_3_' d='M21.2,29.5c-0.2,0-0.5-0.1-0.7-0.3L7.3,16C7.1,15.8,7,15.6,7,15.4s0.1-0.5,0.3-0.7l1.4-1.4 C8.9,13.1,9.1,13,9.4,13c0.2,0,0.5,0.1,0.7,0.3l11.2,11.2l11.2-11.2c0.2-0.2,0.4-0.3,0.7-0.3s0.5,0.1,0.7,0.3l1.4,1.4 c0.2,0.2,0.3,0.4,0.3,0.7S35.2,15.8,35,16L21.8,29.2C21.6,29.4,21.4,29.5,21.2,29.5z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 793:
/***/ (function(module, exports) {

module.exports = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAbsAAAG7AEedTg1AAAAB3RJTUUH2AEDDSAeej84LgAAAgBJREFUOMt1kkFLVFEUx3/n+pyyhcGA0iJzIZHLWliLKWptRdAqoq+RrSIKWkSLaO1HiDRIKMFFgYk0VCa6TByFwdFMwvF53733vdNinOeMTgcuF8655/f/n8MVOkS5XF5P0/RslmWo6nqpVDrHf0IAfk1zZzfhkgK7hcfXY0o3Qgg45wghEPkvnwd7Xn8ygLMsXLnPuzZAtnY5/PF9XfU9MCdvY07dalP5uzlFt39P8TScyLayjdWv0flRFMAAiC131ZMRzlyYoLf/Hs45rLX56e27yeDFCep+BLFlE0lDGCACIFVACd7TXShQLBapVCqINN7FcczOzg6bK1v8dsq1BwwDGbACgC6hq8tPNI5jtdbq4uKihhDUJokmSaLOOXXeq/deQwgaQtAsyxQYPnDQ8GKMwRiDiJCmKWkIiEieQwRVbdtPDpCI3LKI5I15c3PrB7Vm7hCg2lZsVW4Ft4LaAEcVOql1Ah064PgIeuDqKLixh1YHGR0VOgG991hr2bOJA3wDoCDKsfmO3vv7+1SrVUREJycnngKrOYD6DNUlA8DG2jZDQ6/amr331Go1oihievrj87GxRy+ANFJVWRgX5wtzBZgDhe0aMHockCSW2TcP3dsPy8+aq49ERFW1p/Vz3B0YKPZfnX9pjOlu5vas4+f3b3OzPwrjM/MV38z/AxWwCsD6PWYAAAAAAElFTkSuQmCC"

/***/ }),

/***/ 794:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cg%3E %3Cpath d='M20,29.2H7.9c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4V31c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2H20 c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C20.3,29.2,20.1,29.2,20,29.2z'/%3E %3Cpath d='M20,19.5H7.9c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4v1.2c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2H20 c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C20.3,19.5,20.1,19.5,20,19.5z'/%3E %3Cpath d='M20,24.3H7.9c-0.2,0-0.3,0.1-0.4,0.2c-0.1,0.1-0.2,0.3-0.2,0.4v1.2c0,0.2,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2H20 c0.2,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.3,0.2-0.4v-1.2c0-0.2-0.1-0.3-0.2-0.4C20.3,24.4,20.1,24.3,20,24.3z'/%3E %3Cpath d='M27.7,32.1v3.5H3.4V16.2h7.9c0.5,0,0.9-0.2,1.3-0.5s0.5-0.8,0.5-1.3V6.4h14.6v17.8l1.1,1l1.4-1.4V5.8 c0-0.5-0.2-0.9-0.5-1.3S28.8,4,28.3,4h-17c-0.5,0-1.1,0.1-1.7,0.4C9.1,4.6,8.6,4.9,8.2,5.3l-5.9,5.9c-0.4,0.4-0.7,0.8-0.9,1.4 C1.1,13.3,1,13.8,1,14.3v21.9c0,0.5,0.2,0.9,0.5,1.3C1.9,37.8,2.3,38,2.8,38h25.5c0.5,0,0.9-0.2,1.3-0.5c0.4-0.4,0.5-0.8,0.5-1.3 v-4c-0.4,0.2-0.7,0.3-1.2,0.3C28.5,32.5,28.1,32.4,27.7,32.1z M4,12.9L9.9,7c0.2-0.2,0.4-0.3,0.8-0.4v7.1H3.6 C3.7,13.4,3.8,13.1,4,12.9z'/%3E %3Cpath d='M39.7,20.6l-9.9,9.9c-0.2,0.2-0.5,0.3-0.8,0.3c-0.3,0-0.6-0.1-0.8-0.3l-4.7-4.7c-0.2-0.2-0.3-0.5-0.3-0.8 c0-0.3,0.1-0.6,0.3-0.8l0.3-0.3c0.2-0.2,0.5-0.3,0.8-0.3c0.3,0,0.6,0.1,0.8,0.3l3.6,3.6l8.8-8.8c0.2-0.2,0.5-0.3,0.8-0.3 c0.3,0,0.6,0.1,0.8,0.3l0.4,0.4c0.2,0.2,0.3,0.5,0.3,0.8C40,20.1,39.9,20.3,39.7,20.6z'/%3E %3C/g%3E %3C/svg%3E\""

/***/ }),

/***/ 795:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M9.2,5.3c0.4-0.4,0.8-0.7,1.4-0.9C11.3,4.1,11.8,4,12.3,4h17c0.5,0,0.9,0.2,1.3,0.5c0.4,0.4,0.5,0.8,0.5,1.3v30.4 c0,0.5-0.2,0.9-0.5,1.3S29.8,38,29.3,38H3.8c-0.5,0-0.9-0.2-1.3-0.5S2,36.7,2,36.2V14.3c0-0.5,0.1-1.1,0.4-1.7 c0.3-0.6,0.6-1.1,0.9-1.4L9.2,5.3z M10.9,7L5,12.9c-0.2,0.2-0.3,0.4-0.4,0.8h7.1V6.6C11.4,6.7,11.1,6.8,10.9,7z M28.7,35.6V6.4H14.2 v7.9c0,0.5-0.2,0.9-0.5,1.3s-0.8,0.5-1.3,0.5H4.4v19.4H28.7z M24.8,21.3c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.5,0.2H9 c-0.2,0-0.4-0.1-0.5-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.5-0.2h15.1c0.2,0,0.4,0.1,0.5,0.2 c0.1,0.1,0.2,0.3,0.2,0.4V21.3z M24.1,24.3c0.2,0,0.4,0.1,0.5,0.2c0.1,0.1,0.2,0.3,0.2,0.4v1.2c0,0.2-0.1,0.3-0.2,0.4 c-0.1,0.1-0.3,0.2-0.5,0.2H9c-0.2,0-0.4-0.1-0.5-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.5-0.2 H24.1z M24.1,29.2c0.2,0,0.4,0.1,0.5,0.2c0.1,0.1,0.2,0.3,0.2,0.4V31c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.2-0.5,0.2H9 c-0.2,0-0.4-0.1-0.5-0.2c-0.1-0.1-0.2-0.3-0.2-0.4v-1.2c0-0.2,0.1-0.3,0.2-0.4c0.1-0.1,0.3-0.2,0.5-0.2H24.1z M39.7,34.7L36.4,38 l-3.3-3.3L33,19.4l6.6,0L39.7,34.7z M35.3,34.7l1.1-1.1l1.1,1.1l0.6-0.6l0-2.7l-3.5,0l0,2.7L35.3,34.7z M37.4,21.2l0.1,8 c0,0.3,0.1,0.4,0.4,0.4c0.2,0,0.4-0.1,0.4-0.4l-0.1-8c0-0.3-0.1-0.4-0.4-0.4S37.4,20.9,37.4,21.2z M33.4,14.7 c0.3-0.3,0.7-0.5,1.1-0.5l3.5,0c0.4,0,0.8,0.1,1.1,0.5c0.3,0.3,0.5,0.7,0.5,1.1l0,2.1l-6.6,0l0-2.1C33,15.4,33.1,15,33.4,14.7z'/%3E %3C/svg%3E\""

/***/ }),

/***/ 95:
/***/ (function(module, exports) {

module.exports = "\"data:image/svg+xml,%3C?xml version='1.0' encoding='utf-8'?%3E %3C!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E %3Csvg version='1.1' id='Ebene_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 42.5 42.5' style='enable-background:new 0 0 42.5 42.5;' xml:space='preserve'%3E %3Cpath d='M30.6,38c1.3,0,2.4-0.5,3.3-1.6s1.4-2.3,1.4-3.8c0-3.5-0.6-6.3-1.7-8.3s-2.8-3.1-5-3.2c-2.1,1.9-4.6,2.8-7.4,2.8 s-5.3-0.9-7.4-2.8c-2.2,0.1-3.8,1.2-5,3.2S7,29,7,32.5c0,1.5,0.5,2.8,1.4,3.8s2,1.6,3.3,1.6H30.6z'/%3E %3Cpath d='M30.3,10.6c0,0.2-0.1,0.3-0.3,0.5l-3.9,3.8l0.9,5.3c0,0,0,0.1,0,0.2c0,0.1,0,0.3-0.1,0.4s-0.2,0.2-0.3,0.2 c-0.1,0-0.3,0-0.4-0.1l-4.8-2.5l-4.8,2.5c-0.2,0.1-0.3,0.1-0.4,0.1c-0.1,0-0.3-0.1-0.3-0.2c-0.1-0.1-0.1-0.2-0.1-0.4 c0,0,0-0.1,0-0.2l0.9-5.3l-3.9-3.8c-0.2-0.2-0.3-0.4-0.3-0.5c0-0.3,0.2-0.4,0.6-0.5l5.3-0.8l2.4-4.8C21,4.1,21.2,4,21.4,4 c0.2,0,0.4,0.1,0.5,0.4l2.4,4.8l5.3,0.8C30.1,10.1,30.3,10.3,30.3,10.6z'/%3E %3C/svg%3E\""

/***/ })

/******/ });
});