phone number 1

This commit is contained in:
Yuri Kuznetsov
2014-07-02 12:24:42 +03:00
parent b3023192d0
commit d138a5d0b7
38 changed files with 470 additions and 84 deletions
+28 -5
View File
@@ -62,6 +62,7 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
protected function handleSelectParams(&$params, $entityName = false)
{
$this->handleEmailAddressParams($params, $entityName);
$this->handlePhoneNumberParams($params, $entityName);
}
protected function handleEmailAddressParams(&$params, $entityName = false)
@@ -81,11 +82,33 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
if (empty($params['joinConditions'])) {
$params['joinConditions'] = array();
}
$params['leftJoins'] = array('emailAddresses');
$params['joinConditions'] = array(
'emailAddresses' => array(
'primary' => 1
)
$params['leftJoins'][] = 'emailAddresses';
$params['joinConditions']['emailAddresses'] = array(
'primary' => 1
);
}
}
protected function handlePhoneNumberParams(&$params, $entityName = false)
{
if (empty($entityName)) {
$entityName = $this->entityName;
}
$defs = $this->getEntityManager()->getMetadata()->get($entityName);
if (!empty($defs['relations']) && array_key_exists('phoneNumbers', $defs['relations'])) {
if (empty($params['leftJoins'])) {
$params['leftJoins'] = array();
}
if (empty($params['whereClause'])) {
$params['whereClause'] = array();
}
if (empty($params['joinConditions'])) {
$params['joinConditions'] = array();
}
$params['leftJoins'][] = 'phoneNumbers';
$params['joinConditions']['phoneNumbers'] = array(
'primary' => 1
);
}
}
@@ -0,0 +1,76 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
namespace Espo\Core\Utils\Database\Orm\Fields;
class Phone extends \Espo\Core\Utils\Database\Orm\Base
{
public function load($entity, $field)
{
return array(
$entity['name'] => array(
'fields' => array(
$field['name'] => array(
'select' => 'phone_number.name',
'where' =>
array (
'LIKE' => 'phone_number.name LIKE \'{text}\'',
'=' => 'phone_number.name = \'{text}\'',
),
'orderBy' => 'phone_number.name {direction}',
),
$field['name'] .'Data' => array(
'type' => 'text',
'notStorable' => true
),
),
'relations' => array(
$field['name'].'s' => array(
'type' => 'manyMany',
'entity' => 'PhoneNumber',
'relationName' => 'entityPhoneNumber',
'midKeys' => array(
'entity_id',
'phone_number_id',
),
'conditions' => array(
'entityType' => $entity['name'],
),
'additionalColumns' => array(
'entityType' => array(
'type' => 'varchar',
'len' => 100,
),
'primary' => array(
'type' => 'bool',
'default' => false,
),
),
),
),
),
);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
namespace Espo\Entities;
use Espo\Core\Exceptions\Error;
class PhoneNumber extends \Espo\Core\ORM\Entity
{
protected function setName($value)
{
if (empty($value)) {
throw new Error("Phone number can't be empty");
}
$this->valuesContainer['name'] = $value;
}
}
@@ -3,8 +3,7 @@
"name": "Name",
"emailAddress": "Email",
"website": "Website",
"phone": "Phone",
"fax": "Fax",
"phoneNumber": "Phone",
"billingAddress": "Billing Address",
"shippingAddress": "Shipping Address",
"description": "Description",
@@ -4,9 +4,7 @@
"emailAddress": "Email",
"title": "Title",
"account": "Account",
"phone": "Phone",
"phoneOffice": "Phone (Office)",
"fax": "Fax",
"phoneNumber": "Phone",
"accountType": "Account Type",
"doNotCall": "Do Not Call",
"address": "Address",
@@ -9,9 +9,7 @@
"emailAddress": "Email",
"title": "Title",
"website": "Website",
"phone": "Phone",
"phoneOffice": "Phone (Office)",
"fax": "Fax",
"phoneNumber": "Phone",
"accountName": "Account Name",
"doNotCall": "Do Not Call",
"address": "Address",
@@ -5,9 +5,7 @@
"title": "Title",
"website": "Website",
"accountName": "Account Name",
"phone": "Phone",
"phoneOffice": "Phone (Office)",
"fax": "Fax",
"phoneNumber": "Phone",
"doNotCall": "Do Not Call",
"address": "Address",
"description": "Description"
@@ -1 +1,19 @@
[{"label":"Overview","rows":[[{"name":"name"},false],[{"name":"website"},{"name":"phone"}],[{"name":"emailAddress"},{"name":"fax"}],[{"name":"billingAddress"},{"name":"shippingAddress"}],[{"name":"description"},false]]},{"label":"Details","rows":[[{"name":"type"},{"name":"sicCode"}],[{"name":"industry"},false]]}]
[
{
"label":"Overview",
"rows": [
[{"name":"name"},false],
[{"name":"emailAddress"},{"name":"phoneNumber"}],
[{"name":"website"},false],
[{"name":"billingAddress"},{"name":"shippingAddress"}],
[{"name":"description"},false]
]
},
{
"label":"Details",
"rows": [
[{"name":"type"},{"name":"sicCode"}],
[{"name":"industry"},false]
]
}
]
@@ -1 +1,18 @@
[{"label":"Overview","rows":[[{"name":"name"},false],[{"name":"website"},{"name":"phone"}],[{"name":"emailAddress"},{"name":"fax"}],[{"name":"billingAddress"},{"name":"shippingAddress"}],[{"name":"description"},false]]},{"label":"Details","rows":[[{"name":"type"},{"name":"sicCode"}],[{"name":"industry"},false]]}]
[
{
"label":"Overview",
"rows":[
[{"name":"name"},false],
[{"name":"website"},{"name":"phoneNumber"}],
[{"name":"emailAddress"},false],
[{"name":"billingAddress"},{"name":"shippingAddress"}],
[{"name":"description"},false]
]
}, {
"label":"Details",
"rows":[
[{"name":"type"},{"name":"sicCode"}],
[{"name":"industry"},false]
]
}
]
@@ -1 +1 @@
[{"label":"","rows":[[{"name":"name"}],[{"name":"website"}],[{"name":"emailAddress"}],[{"name":"phone"}]]}]
[{"label":"","rows":[[{"name":"name"}],[{"name":"website"}],[{"name":"emailAddress"}],[{"name":"phoneNumber"}]]}]
@@ -1 +1 @@
[{"name":"name","width":30,"link":true},{"name":"website"},{"name":"phone"},{"name":"billingAddressCity"}]
[{"name":"name","width":30,"link":true},{"name":"website"},{"name":"phoneNumber"},{"name":"billingAddressCity"}]
@@ -1 +1 @@
[{"name":"name","link":true},{"name":"website"},{"name":"phone"}]
[{"name":"name","link":true},{"name":"website"},{"name":"phoneNumber"}]
@@ -1 +1,11 @@
[{"label":"Overview","rows":[[{"name":"name"},{"name":"account"}],[{"name":"emailAddress"},{"name":"phone"}],[{"name":"title"},{"name":"doNotCall"}],[{"name":"address"},false],[{"name":"description"},false]]}]
[
{
"label":"Overview",
"rows":[
[{"name":"name"},{"name":"account"}],
[{"name":"emailAddress"},{"name":"phoneNumber"}],
[{"name":"title"},{"name":"doNotCall"}],
[{"name":"address"},false],[{"name":"description"},false]
]
}
]
@@ -1 +1,12 @@
[{"label":"Overview","rows":[[{"name":"name"}],[{"name":"emailAddress"},{"name":"phone"}],[{"name":"title"},{"name":"doNotCall"}],[{"name":"address"},false],[{"name":"description"},false]]}]
[
{
"label":"Overview",
"rows": [
[{"name":"name"}],
[{"name":"emailAddress"},{"name":"phoneNumber"}],
[{"name":"title"},{"name":"doNotCall"}],
[{"name":"address"},false],
[{"name":"description"},false]
]
}
]
@@ -1 +1 @@
[{"label":"","rows":[[{"name":"name"}],[{"name":"account"}],[{"name":"emailAddress"}],[{"name":"phone"}]]}]
[{"label":"","rows":[[{"name":"name"}],[{"name":"account"}],[{"name":"emailAddress"}],[{"name":"phoneNumber"}]]}]
@@ -1 +1 @@
[{"name":"name","width":30,"link":true},{"name":"account","width":20},{"name":"emailAddress"},{"name":"phone"}]
[{"name":"name","width":30,"link":true},{"name":"account","width":20},{"name":"emailAddress"},{"name":"phoneNumber"}]
@@ -1 +1 @@
[{"name":"name","link":true},{"name":"account"},{"name":"phone"},{"name":"emailAddress"}]
[{"name":"name","link":true},{"name":"account"},{"name":"phoneNumber"},{"name":"emailAddress"}]
@@ -1 +1 @@
[{"name":"name","width":35,"link":"true"},{"name":"account"},{"name":"emailAddress"},{"name":"phone"}]
[{"name":"name","width":35,"link":"true"},{"name":"account"},{"name":"emailAddress"},{"name":"phoneNumber"}]
@@ -1 +1,17 @@
[{"label":"Overview","rows":[[{"name":"name"},{"name":"accountName"}],[{"name":"emailAddress"},{"name":"phone"}],[{"name":"title"},{"name":"doNotCall"}],[{"name":"address"},{"name":"website"}],[{"name":"description"},false]]},{"label":"Details","rows":[[{"name":"status"},{"name":"source"}],[{"name":"opportunityAmount"},false]]}]
[
{
"label":"Overview",
"rows": [
[{"name":"name"},{"name":"accountName"}],
[{"name":"emailAddress"},{"name":"phoneNumber"}],
[{"name":"title"},{"name":"doNotCall"}],
[{"name":"address"},{"name":"website"}],
[{"name":"description"},false]]
}, {
"label":"Details",
"rows": [
[{"name":"status"},{"name":"source"}],
[{"name":"opportunityAmount"},false]
]
}
]
@@ -9,7 +9,7 @@
{"name":"emailAddress"}
],
[
{"name":"phone"}
{"name":"phoneNumber"}
],
[
{"name":"status"}
@@ -1 +1 @@
[{"label":"Overview","rows":[[{"name":"name"},{"name":"accountName"}],[{"name":"emailAddress"},{"name":"phone"}],[{"name":"title"},{"name":"doNotCall"}],[{"name":"address"},{"name":"website"}],[{"name":"description"},false]]}]
[{"label":"Overview","rows":[[{"name":"name"},{"name":"accountName"}],[{"name":"emailAddress"},{"name":"phoneNumber"}],[{"name":"title"},{"name":"doNotCall"}],[{"name":"address"},{"name":"website"}],[{"name":"description"},false]]}]
@@ -1 +1 @@
[{"label":"","rows":[[{"name":"name"}],[{"name":"emailAddress"}],[{"name":"phone"}]]}]
[{"label":"","rows":[[{"name":"name"}],[{"name":"emailAddress"}],[{"name":"phoneNumber"}]]}]
@@ -1 +1 @@
[{"name":"name","width":30,"link":true},{"name":"emailAddress"},{"name":"phone"},{"name":"accountName"},{"name":"createdAt"}]
[{"name":"name","width":30,"link":true},{"name":"emailAddress"},{"name":"phoneNumber"},{"name":"accountName"},{"name":"createdAt"}]
@@ -1 +1 @@
[{"name":"name","width":30,"link":true},{"name":"emailAddress"},{"name":"phone"}]
[{"name":"name","width":30,"link":true},{"name":"emailAddress"},{"name":"phoneNumber"}]
@@ -10,11 +10,9 @@
"emailAddress": {
"type": "email"
},
"phone": {
"type": "phone"
},
"fax": {
"type": "phone"
"phoneNumber": {
"type": "phone",
"options": ["Office", "Fax", "Other"]
},
"type": {
"type": "enum",
@@ -28,21 +28,13 @@
"emailAddress": {
"type": "email"
},
"phone": {
"phoneNumber": {
"type": "phone",
"maxLength": 50
},
"fax": {
"type": "phone",
"maxLength": 50
"options": ["Mobile", "Office", "Home", "Fax", "Other"]
},
"doNotCall": {
"type": "bool"
},
"phoneOffice": {
"type": "phone",
"maxLength": 50
},
"address": {
"type": "address"
},
@@ -67,17 +67,9 @@
"emailAddress": {
"type": "email"
},
"phone": {
"phoneNumber": {
"type": "phone",
"maxLength": 50
},
"fax": {
"type": "phone",
"maxLength": 50
},
"phoneOffice": {
"type": "phone",
"maxLength": 50
"options": ["Mobile", "Office", "Home", "Fax", "Other"]
},
"doNotCall": {
"type": "bool"
@@ -183,7 +175,6 @@
},
"Account": {
"name": "accountName",
"phone": "phoneOffice",
"billingAddressStreet": "addressStreet",
"billingAddressCity": "addressCity",
"billingAddressState": "addressState",
@@ -52,17 +52,9 @@
"emailAddress": {
"type": "email"
},
"phone": {
"phoneNumber": {
"type": "phone",
"maxLength": 50
},
"fax": {
"type": "phone",
"maxLength": 50
},
"phoneOffice": {
"type": "phone",
"maxLength": 50
"options": ["Mobile", "Office", "Home", "Fax", "Other"]
},
"doNotCall": {
"type": "bool"
@@ -6,7 +6,7 @@
"isAdmin": "Is Admin",
"defaultTeam": "Default Team",
"emailAddress": "Email",
"phone": "Phone",
"phoneNumber": "Phone",
"roles": "Roles",
"password": "Password",
"passwordConfirm": "Confirm Password",
@@ -5,7 +5,7 @@
[{"name":"userName"},{"name":"isAdmin"}],
[{"name":"name"},{"name":"title"}],
[{"name":"defaultTeam"}],
[{"name":"emailAddress"},{"name":"phone"}]
[{"name":"emailAddress"},{"name":"phoneNumber"}]
]
}
]
@@ -1 +1,11 @@
[{"label":"","rows":[[{"name":"name"}],[{"name":"userName"}],[{"name":"isAdmin"}],[{"name":"emailAddress"}]]}]
[
{
"label":"",
"rows": [
[{"name":"name"}],
[{"name":"userName"}],
[{"name":"isAdmin"}],
[{"name":"emailAddress"}]
]
}
]
@@ -0,0 +1,18 @@
{
"fields": {
"name": {
"type": "varchar",
"required": true,
"maxLength": 36
},
"type": {
"type": "enum"
}
},
"links": {
},
"collection": {
"sortBy": "name",
"asc": true
}
}
@@ -39,9 +39,9 @@
"type": "email",
"required": false
},
"phone": {
"phoneNumber": {
"type": "phone",
"maxLength": 50
"options": ["Mobile", "Office", "Home", "Fax", "Other"]
},
"token": {
"type": "varchar",
@@ -7,7 +7,7 @@
}
],
"notActualFields":[
"Data"
"data"
],
"notCreatable": true,
"search":{
@@ -6,20 +6,20 @@
"default":false
},
{
"name":"default",
"type":"varchar"
},
{
"name":"maxLength",
"type":"int",
"defalut":50
"name":"options",
"type":"array",
"options": ["Mobile", "Office", "Home", "Fax", "Other"]
}
],
"notActualFields":[
"data"
],
"notCreatable": true,
"search":{
"basic":true,
"advanced":true
},
"fieldDefs":{
"type":"varchar"
"notStorable":true
}
}
@@ -0,0 +1,7 @@
{
"entity": true,
"layouts": false,
"tab": false,
"acl": false,
"customizable":false
}
@@ -0,0 +1 @@
<a href="javascript:" data-email-address="{{value}}" data-action="mailTo">{{value}}</a>
+177 -1
View File
@@ -25,10 +25,186 @@ Espo.define('Views.Fields.Phone', 'Views.Fields.Base', function (Dep) {
type: 'phone',
editTemplate: 'fields.phone.edit',
detailTemplate: 'fields.phone.detail',
listTemplate: 'fields.phone.detail',
listTemplate: 'fields.phone.list',
validations: ['required'],
validateRequired: function () {
if (this.params.required || this.model.isRequired(this.name)) {
if (this.model.get(this.name) === '') {
var msg = this.translate('fieldIsRequired', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
this.showValidationMessage(msg, 'div.phone-number-block:nth-child(1) input');
return true;
}
}
},
data: function () {
var phoneNumberData;
if (this.mode == 'edit') {
phoneNumberData = Espo.Utils.clone(this.model.get(this.dataFieldName));
if (this.model.isNew()) {
if (!this.defaultType) {
this.defaultType = (this.getMetadata().get('entityDefs.' + this.model.name + '.fields.' + this.name + '.options') || [''])[0];
}
if (!phoneNumberData || !phoneNumberData.length) {
phoneNumberData = [{
phoneNumber: '',
primary: true,
type: this.defaultType,
}];
}
}
} else {
phoneNumberData = this.model.get(this.dataFieldName) || false;
}
return _.extend({
phoneNumberData: phoneNumberData
}, Dep.prototype.data.call(this));
},
events: {
'click [data-action="switchPhoneProperty"]': function (e) {
var $target = $(e.currentTarget);
var $block = $(e.currentTarget).closest('div.phone-number-block');
var property = $target.data('property-type');
if (property == 'primary') {
if (!$target.hasClass('active')) {
if ($block.find('input.phone-number').val() != '') {
this.$el.find('button.phone-property[data-property-type="primary"]').removeClass('active').children().addClass('text-muted');
$target.addClass('active').children().removeClass('text-muted');
}
}
} else {
if ($target.hasClass('active')) {
$target.removeClass('active').children().addClass('text-muted');
} else {
$target.addClass('active').children().removeClass('text-muted');
}
}
this.fetchToModel();
},
'click [data-action="removePhoneNumber"]': function (e) {
var $block = $(e.currentTarget).closest('div.phone-number-block');
if ($block.parent().children().size() == 1) {
$block.find('input.phone-number').val('');
} else {
this.removePhoneNumberBlock($block);
}
this.fetchToModel();
},
'change input.phone-number': function (e) {
var $input = $(e.currentTarget);
var $block = $input.closest('div.phone-number-block');
if ($input.val() == '') {
if ($block.parent().children().size() == 1) {
$block.find('input.phone-number').val('');
} else {
this.removePhoneNumberBlock($block);
}
}
this.fetchToModel();
},
'click [data-action="addPhoneNumber"]': function () {
var data = this.fetchPhoneNumberData();
o = {
phoneNumber: '',
primary: data.length ? false : true,
type: false
};
data.push(o);
this.model.set(this.dataFieldName, data, {silent: true});
this.render();
},
},
removePhoneNumberBlock: function ($block) {
var changePrimary = false;
if ($block.find('button[data-property-type="primary"]').hasClass('active')) {
changePrimary = true;
}
$block.remove();
if (changePrimary) {
this.$el.find('button[data-property-type="primary"]').first().addClass('active').children().removeClass('text-muted');
}
},
setup: function () {
this.dataFieldName = this.name + 'Data';
if (this.mode == 'detail' || this.mode == 'edit') {
this.listenTo(this.model, 'change:' + this.dataFieldName, function () {
this.render();
}, this);
}
},
fetchPhoneNumberData: function () {
var data = [];
var $list = this.$el.find('div.phone-number-block');
if ($list.size()) {
$list.each(function (i, d) {
var row = {};
var $d = $(d);
row.phoneNumber = $d.find('input.phone-number').val();
if (row.phoneNumber == '') {
return;
}
row.primary = $d.find('button[data-property-type="primary"]').hasClass('active');
row.type = $d.find('select[data-property-type="type"]').val();
data.push(row);
}.bind(this));
}
return data;
},
fetch: function () {
var data = {};
var adderssData = this.fetchPhoneNumberData();
data[this.dataFieldName] = adderssData;
data[this.name] = null;
if (adderssData.length) {
data[this.name] = adderssData[0].phoneNumber;
}
return data;
},
fetchSearch: function () {
var value = this.$element.val() || null;
if (value) {
value += '%';
var data = {
type: 'like',
value: value,
};
return data;
}
return false;
},
});
});