Merge remote-tracking branch 'upstream/develop' into socialnetworks

This commit is contained in:
Frédéric FRANCE 2019-09-30 19:34:35 +02:00
commit b87610adcc
No known key found for this signature in database
GPG Key ID: 06809324E4B2ABC1
138 changed files with 7618 additions and 395 deletions

View File

@ -410,3 +410,9 @@ source_file = htdocs/langs/en_US/workflow.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.zapier]
file_filter = htdocs/langs/<lang>/zapier.lang
source_file = htdocs/langs/en_US/zapier.lang
source_lang = en_US
type = MOZILLAPROPERTIES

View File

@ -22,6 +22,7 @@ Following changes may create regressions for some external modules, but were nec
* Removed deprecated method actioncomm->add(), use create() instead
* If you have developed your own emailing target selector and used parent::add_to_target(...), you must now use parent::addToTargets(...)
* Removed function dol_micro_time. Use native PHP microtime instead.
* The trigger BON_PRELEVEMENT_CREATE has been renamed into DIRECT_DEBIT_ORDER_CREATE.
***** ChangeLog for 10.0.2 compared to 10.0.1 *****

7
dev/examples/zapier/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
build
docs
node_modules
*.log
.environment
.env
.zapierapprc

View File

@ -0,0 +1,7 @@
language: node_js
node_js:
- 8.10.0
before_script: 'npm install -g zapier-platform-cli'
script: 'zapier test'
notifications:
email: false

View File

@ -0,0 +1,56 @@
{
"table_rowid": "id",
"id": 6764,
"ref": null,
"type_id": "5",
"type_code": "AC_RDV",
"type": null,
"type_color": null,
"code": null,
"label": "azerty",
"datec": null,
"datem": null,
"authorid": null,
"usermodid": null,
"datep": 1555365600,
"datef": 1555538399,
"durationp": 172799,
"fulldayevent": 1,
"punctual": 1,
"percentage": "-1",
"location": "",
"transparency": 1,
"priority": 0,
"userassigned": {
"1": {
"id": "1",
"transparency": 1
}
},
"userownerid": "1",
"userdoneid": null,
"usertodo": null,
"userdone": null,
"socid": null,
"contactid": null,
"elementtype": "",
"icalname": null,
"icalcolor": null,
"actions": [],
"email_msgid": null,
"email_from": null,
"email_sender": null,
"email_to": null,
"email_tocc": null,
"email_tobcc": null,
"email_subject": null,
"errors_to": null,
"import_key": null,
"linkedObjectsIds": null,
"fk_project": 0,
"modelpdf": null,
"note_public": null,
"note_private": null,
"note": "wxcvbn",
"duree": 0
}

View File

@ -0,0 +1,77 @@
/*jshint esversion: 6 */
const testAuth = (z , bundle) => {
const url = bundle.authData.url+'/api/index.php/login';
// Normally you want to make a request to an endpoint that is either specifically designed to test auth, or one that
// every user will have access to, such as an account or profile endpoint like /me.
// In this example, we'll hit httpbin, which validates the Authorization Header against the arguments passed in the URL path
const promise = z.request({
url: url,
});
// This method can return any truthy value to indicate the credentials are valid.
// Raise an error to show
return promise.then((response) => {
if (response.status === 401) {
throw new Error('The Session Key you supplied is invalid');
}
return response;
});
};
const getSessionKey = (z, bundle) => {
const url = bundle.authData.url + '/api/index.php/login';
const promise = z.request({
method: 'POST',
url: url,
body: {
login: bundle.authData.login,
password: bundle.authData.password,
}
});
return promise.then((response) => {
if (response.status === 401) {
throw new Error('The login/password you supplied is invalid');
}
const json = JSON.parse(response.content);
return {
sessionKey: json.success.token || 'secret'
};
});
};
module.exports = {
type: 'session',
// Define any auth fields your app requires here. The user will be prompted to enter this info when
// they connect their account.
fields: [
{
key: 'url',
label: 'Url of service',
required: true,
type: 'string'
},
{
key: 'login',
label: 'Login',
required: true,
type: 'string'
},
{
key: 'password',
label: 'Password',
required: true,
type: 'password'
}
],
// The test method allows Zapier to verify that the credentials a user provides are valid. We'll execute this
// method whenever a user connects their account for the first time.
test: testAuth,
// The method that will exchange the fields provided by the user for session credentials.
sessionConfig: {
perform: getSessionKey
},
// assuming "login" is a key returned from the test
connectionLabel: '{{login}}'
};

View File

@ -0,0 +1,90 @@
/*jshint esversion: 6 */
// create a particular thirdparty by name
const createThirdparty = async (z, bundle) => {
const apiurl = bundle.authData.url + '/api/index.php/thirdparties';
const response = await z.request({
method: 'POST',
url: apiurl,
body: JSON.stringify({
name: bundle.inputData.name,
name_alias: bundle.inputData.name_alias,
ref_ext: bundle.inputData.ref_ext,
ref_int: bundle.inputData.ref_int,
address: bundle.inputData.address,
zip: bundle.inputData.zip,
town: bundle.inputData.town,
country_code: bundle.inputData.country_code,
country_id: bundle.inputData.country_id,
country: bundle.inputData.country,
phone: bundle.inputData.phone,
email: bundle.inputData.email,
client: bundle.inputData.client,
fournisseur: bundle.inputData.fournisseur,
code_client: bundle.inputData.code_client,
code_fournisseur: bundle.inputData.code_fournisseur,
sens: 'fromzapier'
})
});
const result = z.JSON.parse(response.content);
// api returns an integer when ok, a json when ko
return result.response || {id: response};
};
module.exports = {
key: 'thirdparty',
noun: 'Thirdparty',
display: {
label: 'Create Thirdparty',
description: 'Creates a thirdparty.'
},
operation: {
inputFields: [
{key: 'name', required: true},
{key: 'name_alias', required: false},
{key: 'address', required: false},
{key: 'zip', required: false},
{key: 'town', required: false},
{key: 'email', required: false},
{key: 'client', type: 'integer', required: false},
{key: 'fournisseur', type: 'integer', required: false},
{key: 'code_client', required: false},
{key: 'code_fournisseur', required: false}
],
perform: createThirdparty,
sample: {
id: 1,
name: 'DUPOND',
name_alias: 'DUPOND Ltd',
address: 'Rue des Canaries',
zip: '34090',
town: 'MONTPELLIER',
phone: '0123456789',
fax: '2345678901',
email: 'robot@domain.com',
client: 1,
fournisseur: 0,
code_client: 'CU1903-1234',
code_fournisseur: 'SU1903-2345'
},
outputFields: [
{key: 'id', label: 'ID'},
{key: 'name', label: 'Name'},
{key: 'name_alias', label: 'Name alias'},
{key: 'address', label: 'Address'},
{key: 'zip', label: 'Zip'},
{key: 'town', label: 'Town'},
{key: 'phone', label: 'Phone'},
{key: 'fax', label: 'Fax'},
{key: 'email', label: 'Email'},
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
{key: 'fournisseur', label: 'Supplier 0/1'},
{key: 'code_client', label: 'Customer code'},
{key: 'code_fournisseur', label: 'Supplier code'}
]
}
};

View File

@ -0,0 +1,73 @@
/*jshint esversion: 6 */
const triggerThirdparty = require('./triggers/thirdparty');
const triggerOrder = require('./triggers/order');
const triggerAction = require('./triggers/action');
const searchThirdparty = require('./searches/thirdparty');
const createThirdparty = require('./creates/thirdparty');
const authentication = require('./authentication');
// To include the session key header on all outbound requests, simply define a function here.
// It runs runs before each request is sent out, allowing you to make tweaks to the request in a centralized spot
const includeSessionKeyHeader = (request, z, bundle) => {
if (bundle.authData.sessionKey) {
request.headers = request.headers || {};
request.headers['DOLAPIKEY'] = bundle.authData.sessionKey;
}
return request;
};
// If we get a response and it is a 401, we can raise a special error telling Zapier to retry this after another exchange.
const sessionRefreshIf401 = (response, z, bundle) => {
if (bundle.authData.sessionKey) {
if (response.status === 401) {
throw new z.errors.RefreshAuthError('Session apikey needs refreshing.');
}
}
return response;
};
// We can roll up all our behaviors in an App.
const App = {
// This is just shorthand to reference the installed dependencies you have. Zapier will
// need to know these before we can upload
version: require('./package.json').version,
platformVersion: require('zapier-platform-core').version,
authentication: authentication,
// beforeRequest & afterResponse are optional hooks into the provided HTTP client
beforeRequest: [
includeSessionKeyHeader
],
afterResponse: [
sessionRefreshIf401
],
// If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!
resources: {
},
// If you want your trigger to show up, you better include it here!
triggers: {
[triggerThirdparty.key]: triggerThirdparty,
[triggerOrder.key]: triggerOrder,
[triggerAction.key]: triggerAction
},
// If you want your searches to show up, you better include it here!
searches: {
[searchThirdparty.key]: searchThirdparty,
},
// If you want your creates to show up, you better include it here!
creates: {
[createThirdparty.key]: createThirdparty,
}
};
// Finally, export the app.
module.exports = App;

405
dev/examples/zapier/package-lock.json generated Normal file
View File

@ -0,0 +1,405 @@
{
"name": "Dolibarr",
"version": "1.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "8.10.20",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.20.tgz",
"integrity": "sha512-M7x8+5D1k/CuA6jhiwuSCmE8sbUWJF0wYsjcig9WrXvwUI5ArEoUBdOXpV4JcEMrLp02/QbDjw+kI+vQeKyQgg==",
"optional": true
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"bluebird": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"browser-stdout": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"diff": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true
},
"dotenv": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz",
"integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow=="
},
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "~0.4.13"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "^2.1.12"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"growl": {
"version": "1.10.5",
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
"dev": true
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"json-tryparse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/json-tryparse/-/json-tryparse-1.0.5.tgz",
"integrity": "sha1-Khy6CLTjEjNo+p+2o01GQwBFeyc="
},
"jsonschema": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.1.1.tgz",
"integrity": "sha1-PO3o4+QR03eHLu+8n98mODy8Ptk="
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"mime-db": {
"version": "1.38.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
"integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
},
"mime-types": {
"version": "2.1.22",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
"integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
"requires": {
"mime-db": "~1.38.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
}
},
"mocha": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
"integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
"dev": true,
"requires": {
"browser-stdout": "1.3.1",
"commander": "2.15.1",
"debug": "3.1.0",
"diff": "3.5.0",
"escape-string-regexp": "1.0.5",
"glob": "7.1.2",
"growl": "1.10.5",
"he": "1.1.1",
"minimatch": "3.0.4",
"mkdirp": "0.5.1",
"supports-color": "5.4.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
"dev": true
},
"node-fetch": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz",
"integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==",
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
}
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"semver": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
},
"should": {
"version": "13.2.3",
"resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz",
"integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==",
"dev": true,
"requires": {
"should-equal": "^2.0.0",
"should-format": "^3.0.3",
"should-type": "^1.4.0",
"should-type-adaptors": "^1.0.1",
"should-util": "^1.0.0"
}
},
"should-equal": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
"integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
"dev": true,
"requires": {
"should-type": "^1.4.0"
}
},
"should-format": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
"integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
"dev": true,
"requires": {
"should-type": "^1.3.0",
"should-type-adaptors": "^1.0.1"
}
},
"should-type": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
"integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=",
"dev": true
},
"should-type-adaptors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
"integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
"dev": true,
"requires": {
"should-type": "^1.3.0",
"should-util": "^1.0.0"
}
},
"should-util": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz",
"integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM=",
"dev": true
},
"supports-color": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"zapier-platform-core": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/zapier-platform-core/-/zapier-platform-core-8.0.1.tgz",
"integrity": "sha512-vuAe7JkFQ88AeQ//NwwNEh8ZjiZr30GRWtwYo7Wo/nx1cqZwq+CRc9zJU2WRrhJfJOtOOTUF6w+pArBTtMOC5A==",
"requires": {
"@types/node": "8.10.20",
"bluebird": "3.5.0",
"content-disposition": "0.5.2",
"dotenv": "5.0.1",
"form-data": "2.3.2",
"lodash": "4.17.11",
"node-fetch": "1.7.1",
"oauth-sign": "0.9.0",
"semver": "5.6.0",
"zapier-platform-schema": "8.0.1"
}
},
"zapier-platform-schema": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/zapier-platform-schema/-/zapier-platform-schema-8.0.1.tgz",
"integrity": "sha512-97KJ0xVLtpU4BiXVaMTPQpiA0T6CQIEzWfzAWwJAWbu5336+6DMFUzDWN4bANBeD3CIsRHHPcZkP8n/17U05ag==",
"requires": {
"jsonschema": "1.1.1",
"lodash": "4.17.10"
},
"dependencies": {
"lodash": {
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
}
}
}
}
}

View File

@ -0,0 +1,24 @@
{
"name": "Dolibarr",
"version": "1.0.0",
"description": "An app for connecting Dolibarr to the Zapier platform.",
"repository": "Dolibarr/dolibarr",
"homepage": "https://www.dolibarr.fr/",
"author": "Frédéric France <frederic.france@netlogic.fr>",
"license": "BSD-3-Clause",
"main": "index.js",
"scripts": {
"test": "mocha --recursive"
},
"engines": {
"node": "8.10.0",
"npm": ">=5.6.0"
},
"dependencies": {
"zapier-platform-core": "8.0.1"
},
"devDependencies": {
"mocha": "^5.2.0",
"should": "^13.2.0"
}
}

View File

@ -0,0 +1,66 @@
module.exports = {
key: 'thirdparty',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Thirdparty',
display: {
label: 'Find a Thirdparty',
description: 'Search for thirdparty.'
},
// `operation` is where we make the call to your API to do the search
operation: {
// This search only has one search field. Your searches might have just one, or many
// search fields.
inputFields: [
{
key: 'name',
type: 'string',
label: 'Name',
helpText: 'Name to limit to the search to (i.e. The company or %company%).'
}
],
perform: (z, bundle) => {
const url = bundle.authData.url + '/api/index.php/thirdparties/';
// Put the search value in a query param. The details of how to build
// a search URL will depend on how your API works.
const options = {
params: {
sqlfilters: "t.nom like \'%"+bundle.inputData.name+"%\'"
}
};
return z.request(url, options).then(response => JSON.parse(response.content));
},
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
id: 1,
createdAt: 1472069465,
name: 'DOE',
firstname: 'John',
authorId: 1,
directions: '1. Boil Noodles\n2.Serve with sauce',
style: 'italian'
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{key: 'id', label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'firstname', label: 'Firstname'},
{key: 'directions', label: 'Directions'},
{key: 'authorId', label: 'Author ID'},
{key: 'style', label: 'Style'}
]
}
};

View File

@ -0,0 +1,17 @@
require('should');
const zapier = require('zapier-platform-core');
// Use this to make test calls into your app:
const App = require('../index');
const appTester = zapier.createAppTester(App);
describe('My App', () => {
it('should test something', (done) => {
const x = 1;
x.should.eql(1);
done();
});
});

View File

@ -0,0 +1,156 @@
const subscribeHook = (z, bundle) => {
// `z.console.log()` is similar to `console.log()`.
z.console.log('suscribing hook!');
// bundle.targetUrl has the Hook URL this app should call when an action is created.
const data = {
url: bundle.targetUrl,
event: bundle.event,
module: 'action',
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: url,
method: 'POST',
body: JSON.stringify(data)
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unsubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
z.console.log('unsuscribing hook!');
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const getAction = (z, bundle) => {
// bundle.cleanedRequest will include the parsed JSON object (if it's not a
// test poll) and also a .querystring property with the URL's query string.
const action = {
id: bundle.cleanedRequest.id,
ref: bundle.cleanedRequest.ref,
ref_client: bundle.cleanedRequest.ref_client,
name: bundle.cleanedRequest.name,
firstname: bundle.cleanedRequest.firstname,
usertodo__name: bundle.cleanedRequest.usertodo__name,
location: bundle.cleanedRequest.location,
label: bundle.cleanedRequest.label,
authorId: bundle.cleanedRequest.authorId,
createdAt: bundle.cleanedRequest.createdAt,
module: bundle.cleanedRequest.module,
datep: bundle.cleanedRequest.datep,
datef: bundle.cleanedRequest.datef,
fulldayevent: bundle.cleanedRequest.fulldayevent,
transparency: bundle.cleanedRequest.transparency,
icalname: bundle.cleanedRequest.icalname,
icalcolor: bundle.cleanedRequest.icalcolor,
note: bundle.cleanedRequest.note,
note_public: bundle.cleanedRequest.note_public,
note_private: bundle.cleanedRequest.note_private,
action: bundle.cleanedRequest.action
};
return [action];
};
const getFallbackRealAction = (z, bundle) => {
// For the test poll, you should get some real data, to aid the setup process.
const module = bundle.inputData.module;
const options = {
url: bundle.authData.url + '/api/index.php/agendaevents/0',
};
return z.request(options).then((response) => [JSON.parse(response.content)]);
};
// const getActionsChoices = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/actions',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
// };
// We recommend writing your actions separate like this and rolling them
// into the App definition at the end.
module.exports = {
key: 'action',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Action',
display: {
label: 'New Agenda',
description: 'Trigger when a new agenda with action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
operation: {
// `inputFields` can define the fields a user could provide,
// we'll pass them in as `bundle.inputData` later.
inputFields: [
{
key: 'action',
type: 'string',
helpText: 'Which action of agenda this should trigger on.',
choices: {
create: "Create",
modify: "Modify",
delete: "Delete",
}
}
],
type: 'hook',
performSubscribe: subscribeHook,
performUnsubscribe: unsubscribeHook,
perform: getAction,
performList: getFallbackRealAction,
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
id: 1,
createdAt: 1472069465,
name: 'Best Spagetti Ever',
authorId: 1,
action: 'create'
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{key: 'id', label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'usertodo__name', label: 'UserToDo Name'},
{key: 'authorId', label: 'Author ID'},
{key: 'action', label: 'Action'}
]
}
};

View File

@ -0,0 +1,148 @@
const subscribeHook = (z, bundle) => {
// `z.console.log()` is similar to `console.log()`.
z.console.log('suscribing hook!');
// bundle.targetUrl has the Hook URL this app should call when an action is created.
const data = {
url: bundle.targetUrl,
event: bundle.event,
module: 'order',
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: url,
method: 'POST',
body: JSON.stringify(data)
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unsubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
z.console.log('unsuscribing hook!');
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const getOrder = (z, bundle) => {
// bundle.cleanedRequest will include the parsed JSON object (if it's not a
// test poll) and also a .querystring property with the URL's query string.
const order = {
id: bundle.cleanedRequest.id,
ref: bundle.cleanedRequest.ref,
ref_client: bundle.cleanedRequest.ref_client,
name: bundle.cleanedRequest.name,
firstname: bundle.cleanedRequest.firstname,
directions: bundle.cleanedRequest.directions,
authorId: bundle.cleanedRequest.authorId,
createdAt: bundle.cleanedRequest.createdAt,
note_public: bundle.cleanedRequest.note_public,
note_private: bundle.cleanedRequest.note_private,
action: bundle.cleanedRequest.action
};
return [order];
};
const getFallbackRealOrder = (z, bundle) => {
// For the test poll, you should get some real data, to aid the setup process.
const module = bundle.inputData.module;
const options = {
url: bundle.authData.url + '/api/index.php/orders/0',
};
return z.request(options).then((response) => [JSON.parse(response.content)]);
};
// const getActionsChoices = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/orders',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
// };
// We recommend writing your orders separate like this and rolling them
// into the App definition at the end.
module.exports = {
key: 'order',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Order',
display: {
label: 'New Order',
description: 'Trigger when a new order with action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
operation: {
// `inputFields` can define the fields a user could provide,
// we'll pass them in as `bundle.inputData` later.
inputFields: [
{
key: 'action',
type: 'string',
helpText: 'Which action of order this should trigger on.',
choices: {
create: "Create",
modify: "Modify",
validate: "Validate",
}
}
],
type: 'hook',
performSubscribe: subscribeHook,
performUnsubscribe: unsubscribeHook,
perform: getOrder,
performList: getFallbackRealOrder,
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
id: 1,
createdAt: 1472069465,
name: 'Best Spagetti Ever',
authorId: 1,
directions: '1. Boil Noodles\n2.Serve with sauce',
action: 'create'
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{key: 'id', label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'directions', label: 'Directions'},
{key: 'authorId', label: 'Author ID'},
{key: 'module', label: 'Module'},
{key: 'action', label: 'Action'}
]
}
};

View File

@ -0,0 +1,175 @@
const subscribeHook = (z, bundle) => {
// `z.console.log()` is similar to `console.log()`.
z.console.log('suscribing hook!');
// bundle.targetUrl has the Hook URL this app should call when an action is created.
const data = {
url: bundle.targetUrl,
event: bundle.event,
module: 'company',
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: url,
method: 'POST',
body: JSON.stringify(data)
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const unsubscribeHook = (z, bundle) => {
// bundle.subscribeData contains the parsed response JSON from the subscribe
// request made initially.
z.console.log('unsuscribing hook!');
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
// You may return a promise or a normal data structure from any perform method.
return z.request(options).then((response) => JSON.parse(response.content));
};
const getThirdparty = (z, bundle) => {
// bundle.cleanedRequest will include the parsed JSON object (if it's not a
// test poll) and also a .querystring property with the URL's query string.
const thirdparty = {
id: bundle.cleanedRequest.id,
name: bundle.cleanedRequest.name,
name_alias: bundle.cleanedRequest.name_alias,
firstname: bundle.cleanedRequest.firstname,
address: bundle.cleanedRequest.address,
zip: bundle.cleanedRequest.zip,
town: bundle.cleanedRequest.town,
email: bundle.cleanedRequest.email,
client: bundle.cleanedRequest.client,
fournisseur: bundle.cleanedRequest.fournisseur,
code_client: bundle.cleanedRequest.code_client,
code_fournisseur: bundle.cleanedRequest.code_fournisseur,
authorId: bundle.cleanedRequest.authorId,
createdAt: bundle.cleanedRequest.createdAt,
action: bundle.cleanedRequest.action
};
return [thirdparty];
};
const getFallbackRealThirdparty = (z, bundle) => {
// For the test poll, you should get some real data, to aid the setup process.
const module = bundle.inputData.module;
const options = {
url: bundle.authData.url + '/api/index.php/thirdparties/0',
};
return z.request(options).then((response) => [JSON.parse(response.content)]);
};
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
// };
// const getModulesChoices = () => {
// return {
// orders: "Order",
// invoices: "Invoice",
// thirdparties: "Thirdparty",
// contacts: "Contacts"
// };
// };
// const getActionsChoices = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));
// };
// We recommend writing your triggers separate like this and rolling them
// into the App definition at the end.
module.exports = {
key: 'thirdparty',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Thirdparty',
display: {
label: 'New Thirdparty',
description: 'Trigger when a new thirdpaty action is done in Dolibarr.'
},
// `operation` is where the business logic goes.
operation: {
// `inputFields` can define the fields a user could provide,
// we'll pass them in as `bundle.inputData` later.
inputFields: [
{
key: 'action',
type: 'string',
helpText: 'Which action of thirdparty this should trigger on.',
choices: {
create: "Create",
modify: "Modify",
validate: "Validate",
}
}
],
type: 'hook',
performSubscribe: subscribeHook,
performUnsubscribe: unsubscribeHook,
perform: getThirdparty,
performList: getFallbackRealThirdparty,
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
id: 1,
createdAt: 1472069465,
name: 'DOE',
name_alias: 'DOE Ltd',
firstname: 'John',
authorId: 1,
action: 'create'
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{key: 'id', label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'name_alias', label: 'Name alias'},
{key: 'firstname', label: 'Firstame'},
{key: 'authorId', label: 'Author ID'},
{key: 'action', label: 'Action'},
{key: 'client', label: 'Customer/Prospect 0/1/2/3'},
{key: 'fournisseur', label: 'Supplier 0/1'},
{key: 'code_client', label: 'Customer code'},
{key: 'code_fournisseur', label: 'Supplier code'}
]
}
};

View File

@ -50,7 +50,7 @@ $hookmanager->initHooks(array('accountancyindex'));
llxHeader('', $langs->trans("AccountancyArea"));
print load_fiche_titre($langs->trans("AccountancyArea"), '', 'title_accountancy');
print load_fiche_titre($langs->trans("AccountancyArea"), '', 'accountancy');
//dol_fiche_head();
$step = 0;

View File

@ -52,7 +52,7 @@ $staticmember=new Adherent($db);
$statictype=new AdherentType($db);
$subscriptionstatic=new Subscription($db);
print load_fiche_titre($langs->trans("MembersArea"));
print load_fiche_titre($langs->trans("MembersArea"), '', 'members');
$Adherents=array();
$AdherentsAValider=array();

View File

@ -419,7 +419,7 @@ print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($titre, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($titre, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$topicmail="Information";
$modelmail="member";
@ -956,7 +956,7 @@ print "</table>\n";
print "</div>";
print '</form>';
if ($num > $limit || $page) print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, '', '', $limit, 1);
if ($num > $limit || $page) print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, '', '', $limit, 1);
// End of page
llxFooter();

View File

@ -262,7 +262,7 @@ print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$topicmail="Information";
$modelmail="subscription";

View File

@ -248,7 +248,7 @@ if (! $rowid && $action != 'create' && $action != 'edit')
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print_barre_liste($langs->trans("MembersTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($langs->trans("MembersTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$moreforfilter = '';

View File

@ -45,7 +45,6 @@ llxHeader('', $langs->trans("Setup"), $wikihelp);
print load_fiche_titre($langs->trans("SetupArea"), '', 'tools');
if (! empty($conf->global->MAIN_MOTD_SETUPPAGE))
{
$conf->global->MAIN_MOTD_SETUPPAGE=preg_replace('/<br(\s[\sa-zA-Z_="]*)?\/?>/i', '<br>', $conf->global->MAIN_MOTD_SETUPPAGE);

View File

@ -237,7 +237,7 @@ if (! $rowid && $action != 'create' && $action != 'edit')
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print_barre_liste($langs->trans("AssetsTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($langs->trans("AssetsTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$moreforfilter = '';

View File

@ -85,7 +85,7 @@ $newcardbutton='';
$newcardbutton.= dolGetButtonTitle($langs->trans('NewBookmark'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer));
print_barre_liste($langs->trans("ListOfBookmarks"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', -1, '', 'title_generic.png', 0, $newcardbutton);
print_barre_liste($langs->trans("ListOfBookmarks"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', -1, '', 'generic', 0, $newcardbutton);
$sql = "SELECT b.rowid, b.dateb, b.fk_user, b.url, b.target, b.title, b.favicon, b.position,";
$sql.= " u.login, u.lastname, u.firstname";

View File

@ -1546,24 +1546,28 @@ if ($id > 0)
print $formconfirm;
}
$linkback =img_picto($langs->trans("BackToList"), 'object_list', 'class="hideonsmartphone pictoactionview"');
$linkback.= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
$linkback='';
// Link to other agenda views
$out='';
$out.='</li>';
$out.='<li class="noborder litext">'.img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="hideonsmartphone pictoactionview"');
$out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_month&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewCal").'</a>';
$out.='</li>';
$out.='<li class="noborder litext">'.img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="hideonsmartphone pictoactionview"');
$out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_week&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewWeek").'</a>';
$out.='</li>';
$out.='<li class="noborder litext">'.img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="hideonsmartphone pictoactionview"');
$out.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_day&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewDay").'</a>';
$out.='</li>';
$out.='<li class="noborder litext">'.img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="hideonsmartphone pictoactionview"');
$out.='<a href="'.DOL_URL_ROOT.'/comm/action/peruser.php?action=show_peruser&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewPerUser").'</a>';
$linkback.=$out;
$linkback.=img_picto($langs->trans("BackToList"), 'object_list', 'class="hideonsmartphone pictoactionview"');
$linkback.='<a href="'.DOL_URL_ROOT.'/comm/action/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
$linkback.='</li>';
$linkback.='<li class="noborder litext">';
$linkback.=img_picto($langs->trans("ViewCal"), 'object_calendar', 'class="hideonsmartphone pictoactionview"');
$linkback.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_month&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewCal").'</a>';
$linkback.='</li>';
$linkback.='<li class="noborder litext">';
$linkback.=img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="hideonsmartphone pictoactionview"');
$linkback.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_week&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewWeek").'</a>';
$linkback.='</li>';
$linkback.='<li class="noborder litext">';
$linkback.=img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="hideonsmartphone pictoactionview"');
$linkback.='<a href="'.DOL_URL_ROOT.'/comm/action/index.php?action=show_day&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewDay").'</a>';
$linkback.='</li>';
$linkback.='<li class="noborder litext">';
$linkback.=img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="hideonsmartphone pictoactionview"');
$linkback.='<a href="'.DOL_URL_ROOT.'/comm/action/peruser.php?action=show_peruser&year='.dol_print_date($object->datep, '%Y').'&month='.dol_print_date($object->datep, '%m').'&day='.dol_print_date($object->datep, '%d').'">'.$langs->trans("ViewPerUser").'</a>';
//$linkback.=$out;
$morehtmlref='<div class="refidno">';
// Thirdparty

View File

@ -1637,7 +1637,7 @@ class ActionComm extends CommonObject
* Used to build previews or test instances.
* id must be 0 if object instance is a specimen.
*
* @return void
* @return int >0 if ok
*/
public function initAsSpecimen()
{
@ -1669,6 +1669,7 @@ class ActionComm extends CommonObject
$this->userownerid=$user->id;
$this->userassigned[$user->id]=array('id'=>$user->id, 'transparency'=> 1);
return 1;
}
/**

View File

@ -64,25 +64,28 @@ class AgendaEvents extends DolibarrApi
public function get($id)
{
if (! DolibarrApiAccess::$user->rights->agenda->myactions->read) {
throw new RestException(401, "Insuffisant rights to read an event");
throw new RestException(401, "Insufficient rights to read an event");
}
if ($id == 0) {
$result = $this->actioncomm->initAsSpecimen();
} else {
$result = $this->actioncomm->fetch($id);
if ($result) {
$this->actioncomm->fetch_optionals();
$this->actioncomm->fetchObjectLinked();
}
}
$result = $this->actioncomm->fetch($id);
if ( ! $result ) {
throw new RestException(404, 'Agenda Events not found');
}
if (! DolibarrApiAccess::$user->rights->agenda->allactions->read && $this->actioncomm->ownerid != DolibarrApiAccess::$user->id) {
throw new RestException(401, "Insuffisant rights to read event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
throw new RestException(401, "Insufficient rights to read event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
}
if ( ! DolibarrApi::_checkAccessToResource('agenda', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) {
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
}
$result = $this->actioncomm->fetch_optionals();
$this->actioncomm->fetchObjectLinked();
return $this->_cleanObjectDatas($this->actioncomm);
}
@ -106,7 +109,7 @@ class AgendaEvents extends DolibarrApi
$obj_ret = array();
if (! DolibarrApiAccess::$user->rights->agenda->myactions->read) {
throw new RestException(401, "Insuffisant rights to read events");
throw new RestException(401, "Insufficient rights to read events");
}
// case of external user
@ -191,10 +194,10 @@ class AgendaEvents extends DolibarrApi
public function post($request_data = null)
{
if (! DolibarrApiAccess::$user->rights->agenda->myactions->create) {
throw new RestException(401, "Insuffisant rights to create your Agenda Event");
throw new RestException(401, "Insufficient rights to create your Agenda Event");
}
if (! DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) {
throw new RestException(401, "Insuffisant rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
}
// Check mandatory fields
@ -230,10 +233,10 @@ class AgendaEvents extends DolibarrApi
public function put($id, $request_data = null)
{
if (! DolibarrApiAccess::$user->rights->agenda->myactions->create) {
throw new RestException(401, "Insuffisant rights to create your Agenda Event");
throw new RestException(401, "Insufficient rights to create your Agenda Event");
}
if (! DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) {
throw new RestException(401, "Insuffisant rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
}
$result = $this->actioncomm->fetch($id);
@ -271,7 +274,7 @@ class AgendaEvents extends DolibarrApi
public function delete($id)
{
if(! DolibarrApiAccess::$user->rights->agenda->myactions->delete) {
throw new RestException(401, "Insuffisant rights to delete your Agenda Event");
throw new RestException(401, "Insufficient rights to delete your Agenda Event");
}
$result = $this->actioncomm->fetch($id);
@ -282,7 +285,7 @@ class AgendaEvents extends DolibarrApi
}
if(! DolibarrApiAccess::$user->rights->agenda->allactions->delete && DolibarrApiAccess::$user->id != $this->actioncomm->userownerid) {
throw new RestException(401, "Insuffisant rights to delete an Agenda Event of owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
throw new RestException(401, "Insufficient rights to delete an Agenda Event of owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id);
}
if( ! $result ) {

View File

@ -174,6 +174,26 @@ if ($action =='delete_action')
/*
* View
*/
$parameters = array(
'socid' => $socid,
'status' => $status,
'year' => $year,
'month' => $month,
'day' => $day,
'type' => $type,
'maxprint' => $maxprint,
'filter' => $filter,
'filtert' => $filtert,
'showbirthday' => $showbirthday,
'canedit' => $canedit,
'optioncss' => $optioncss,
'actioncode' => $actioncode,
'pid' => $pid,
'resourceid' => $resourceid,
'usergroup' => $usergroup,
);
$reshook = $hookmanager->executeHooks('beforeAgenda', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
$help_url='EN:Module_Agenda_En|FR:Module_Agenda|ES:M&oacute;dulo_Agenda';
llxHeader('', $langs->trans("Agenda"), $help_url);

View File

@ -109,6 +109,7 @@ if ($dateselect > 0)
}
$tmp=empty($conf->global->MAIN_DEFAULT_WORKING_HOURS)?'9-18':$conf->global->MAIN_DEFAULT_WORKING_HOURS;
$tmp=str_replace(' ', '', $tmp); // FIX 7533
$tmparray=explode('-', $tmp);
$begin_h = GETPOST('begin_h', 'int')!=''?GETPOST('begin_h', 'int'):($tmparray[0] != '' ? $tmparray[0] : 9);
$end_h = GETPOST('end_h', 'int')?GETPOST('end_h', 'int'):($tmparray[1] != '' ? $tmparray[1] : 18);
@ -117,6 +118,7 @@ if ($end_h < 1 || $end_h > 24) $end_h = 18;
if ($end_h <= $begin_h) $end_h = $begin_h + 1;
$tmp=empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)?'1-5':$conf->global->MAIN_DEFAULT_WORKING_DAYS;
$tmp=str_replace(' ', '', $tmp); // FIX 7533
$tmparray=explode('-', $tmp);
$begin_d = GETPOST('begin_d', 'int')?GETPOST('begin_d', 'int'):($tmparray[0] != '' ? $tmparray[0] : 1);
$end_d = GETPOST('end_d', 'int')?GETPOST('end_d', 'int'):($tmparray[1] != '' ? $tmparray[1] : 5);

View File

@ -86,6 +86,7 @@ $extralabels=$extrafields->fetch_name_optionals_label($object->table_element);
$hookmanager->initHooks(array('thirdpartycomm','globalcard'));
/*
* Actions
*/

View File

@ -79,7 +79,7 @@ if (! empty($conf->fournisseur->enabled)) $supplierorderstatic=new CommandeFourn
llxHeader("", $langs->trans("CommercialArea"));
print load_fiche_titre($langs->trans("CommercialArea"), '', 'title_commercial.png');
print load_fiche_titre($langs->trans("CommercialArea"), '', 'commercial');
print '<div class="fichecenter"><div class="fichethirdleft">';

View File

@ -742,7 +742,7 @@ if ($action == 'create')
// Print mail form
print load_fiche_titre($langs->trans("NewMailing"), $availablelink, 'title_generic');
print load_fiche_titre($langs->trans("NewMailing"), $availablelink, 'generic');
dol_fiche_head();
@ -1117,7 +1117,7 @@ else
$htmltext.='</i>';
// Print mail content
print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto('<span class="hideonsmartphone">'.$langs->trans("AvailableVariables").'</span>', $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'title_generic');
print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto('<span class="hideonsmartphone">'.$langs->trans("AvailableVariables").'</span>', $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'generic');
dol_fiche_head('', '', '', -1);
@ -1262,7 +1262,7 @@ else
$htmltext.='</i>';
// Print mail content
print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'title_generic');
print load_fiche_titre($langs->trans("EMail"), $form->textwithpicto($langs->trans("AvailableVariables"), $htmltext, 1, 'help', '', 0, 2, 'emailsubstitionhelp'), 'generic');
dol_fiche_head(null, '', '', -1);

View File

@ -250,7 +250,7 @@ if ($object->fetch($id) >= 0)
// Show email selectors
if ($allowaddtarget && $user->rights->mailing->creer)
{
print load_fiche_titre($langs->trans("ToAddRecipientsChooseHere"), ($user->admin?info_admin($langs->trans("YouCanAddYourOwnPredefindedListHere"), 1):''), 'title_generic');
print load_fiche_titre($langs->trans("ToAddRecipientsChooseHere"), ($user->admin?info_admin($langs->trans("YouCanAddYourOwnPredefindedListHere"), 1):''), 'generic');
//print '<table class="noborder" width="100%">';
print '<div class="tagtable centpercent liste_titre_bydiv borderbottom" id="tablelines">';
@ -453,7 +453,7 @@ if ($object->fetch($id) >= 0)
if ($allowaddtarget) {
$cleartext=$langs->trans("ToClearAllRecipientsClickHere").' '.'<a href="'.$_SERVER["PHP_SELF"].'?clearlist=1&id='.$object->id.'" class="button reposition">'.$langs->trans("TargetsReset").'</a>';
}
print_barre_liste($langs->trans("MailSelectedRecipients"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $cleartext, $num, $nbtotalofrecords, 'title_generic', 0, '', '', $limit);
print_barre_liste($langs->trans("MailSelectedRecipients"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $cleartext, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
print '</form>';

View File

@ -173,7 +173,7 @@ if ($result)
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', $num, '', 'title_generic.png', 0, $newcardbutton);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', $num, '', 'generic', 0, $newcardbutton);
$moreforfilter = '';

View File

@ -462,7 +462,7 @@ if ($resql)
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'commercial', 0, $newcardbutton, '', $limit);
$topicmail="SendPropalRef";
$modelmail="proposal_send";

View File

@ -80,7 +80,7 @@ if ($mode == 'supplier')
llxHeader('', $title);
print load_fiche_titre($title, '', 'title_commercial.png');
print load_fiche_titre($title, '', 'commercial');
dol_mkdir($dir);

View File

@ -1485,7 +1485,7 @@ if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); }
// Mode creation
if ($action == 'create' && $usercancreate)
{
print load_fiche_titre($langs->trans('CreateOrder'), '', 'title_commercial.png');
print load_fiche_titre($langs->trans('CreateOrder'), '', 'commercial');
$soc = new Societe($db);
if ($socid > 0)

View File

@ -464,7 +464,7 @@ if ($resql)
print '<input type="hidden" name="socid" value="'.$socid.'">';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'commercial', 0, $newcardbutton, '', $limit);
$topicmail="SendOrderRef";
$modelmail="order_send";

View File

@ -79,7 +79,7 @@ if ($mode == 'supplier')
llxHeader('', $title);
print load_fiche_titre($title, '', 'title_commercial.png');
print load_fiche_titre($title, '', 'commercial');
dol_mkdir($dir);

View File

@ -87,7 +87,7 @@ $thirdpartystatic = new Societe($db);
llxHeader("", $langs->trans("AccountancyTreasuryArea"));
print load_fiche_titre($langs->trans("AccountancyTreasuryArea"), '', 'title_accountancy.png');
print load_fiche_titre($langs->trans("AccountancyTreasuryArea"), '', 'invoicing');
print '<div class="fichecenter"><div class="fichethirdleft">';

View File

@ -122,7 +122,7 @@ if ($result)
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($langs->trans("WithdrawalsReceipts"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic', 0, $newcardbutton, '', $limit);
print_barre_liste($langs->trans("WithdrawalsReceipts"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
$moreforfilter='';

View File

@ -772,17 +772,18 @@ class BonPrelevement extends CommonObject
* Create a withdraw
* TODO delete params banque and agence when not necesary
*
* @param int $banque dolibarr mysoc bank
* @param int $agence dolibarr mysoc bank office (guichet)
* @param int $banque dolibarr mysoc bank
* @param int $agence dolibarr mysoc bank office (guichet)
* @param string $mode real=do action, simu=test only
* @param string $format FRST, RCUR or ALL
* @param string $executiondate Date to execute the transfer
* @param string $executiondate Date to execute the transfer
* @param int $notrigger Disable triggers
* @return int <0 if KO, nbre of invoice withdrawed if OK
*/
public function Create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '')
public function Create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '', $notrigger = 0)
{
// phpcs:enable
global $conf,$langs;
global $conf, $langs, $user;
dol_syslog(__METHOD__."::Bank=".$banque." Office=".$agence." mode=".$mode." format=".$format, LOG_DEBUG);
@ -1091,6 +1092,7 @@ class BonPrelevement extends CommonObject
}
$this->factures = $factures_prev_id;
$this->context['factures_prev'] = $factures_prev;
// Generation of SEPA file $this->filename
$this->generate($format, $executiondate);
@ -1114,6 +1116,14 @@ class BonPrelevement extends CommonObject
dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR);
}
if (! $error && ! $notrigger)
{
// Call trigger
$result=$this->call_trigger('DIRECT_DEBIT_ORDER_CREATE', $user);
if ($result < 0) $error++;
// End call triggers
}
if (!$error)
{
$this->db->commit();
@ -1149,7 +1159,7 @@ class BonPrelevement extends CommonObject
if (! $notrigger)
{
// Call trigger
$result=$this->call_trigger('BON_PRELEVEMENT_DELETE', $user);
$result=$this->call_trigger('DIRECT_DEBIT_ORDER_DELETE', $user);
if ($result < 0) $error++;
// End call triggers
}

View File

@ -140,7 +140,7 @@ else
$newcardbutton = '<a href="'.DOL_URL_ROOT.'/compta/prelevement/index.php">'.$langs->trans("Back").'</a>';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';

View File

@ -131,7 +131,7 @@ if ($result)
print"\n<!-- debut table -->\n";
print '<form action="'.$_SERVER["PHP_SELF"].'" method="GET">';
print_barre_liste($langs->trans("WithdrawalsLines"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic', 0, '', '', $limit);
print_barre_liste($langs->trans("WithdrawalsLines"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
$moreforfilter='';

View File

@ -1372,7 +1372,7 @@ class Contact extends CommonObject
* Used to build previews or test instances.
* id must be 0 if object instance is a specimen.
*
* @return void
* @return int >0 if ok
*/
public function initAsSpecimen()
{
@ -1411,6 +1411,7 @@ class Contact extends CommonObject
$this->socid = $socid;
$this->statut=1;
return 1;
}
/**

View File

@ -1112,7 +1112,7 @@ if ($result > 0)
// Create
if ($action == 'create')
{
print load_fiche_titre($langs->trans('AddContract'), '', 'title_commercial.png');
print load_fiche_titre($langs->trans('AddContract'), '', 'commercial');
$soc = new Societe($db);
if ($socid>0) $soc->fetch($socid);

View File

@ -187,7 +187,7 @@ class Contracts extends DolibarrApi
public function post($request_data = null)
{
if(! DolibarrApiAccess::$user->rights->contrat->creer) {
throw new RestException(401, "Insuffisant rights");
throw new RestException(401, "Insufficient rights");
}
// Check mandatory fields
$result = $this->_validate($request_data);

View File

@ -70,7 +70,7 @@ $now = dol_now();
llxHeader();
print load_fiche_titre($langs->trans("ContractsArea"), '', 'title_commercial.png');
print load_fiche_titre($langs->trans("ContractsArea"), '', 'commercial');
//print '<table border="0" width="100%" class="notopnoleftnoright">';

View File

@ -380,7 +380,7 @@ print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $totalnboflines, 'title_commercial.png', 0, $newcardbutton, '', $limit);
print_barre_liste($langs->trans("ListOfContracts"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $totalnboflines, 'commercial', 0, $newcardbutton, '', $limit);
$topicmail="SendContractRef";
$modelmail="contract";

View File

@ -336,7 +336,7 @@ if ($mode == "0") $title=$langs->trans("ListOfInactiveServices"); // Must use ==
if ($mode == "4" && $filter != "expired") $title=$langs->trans("ListOfRunningServices");
if ($mode == "4" && $filter == "expired") $title=$langs->trans("ListOfExpiredServices");
if ($mode == "5") $title=$langs->trans("ListOfClosedServices");
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'commercial', 0, '', '', $limit);
if ($sall)
{

View File

@ -69,22 +69,22 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes
*/
public function loadBox($max = 5)
{
global $conf, $user, $langs, $db;
$langs->loadLangs(array("boxes", "sendings"));
global $conf, $user, $langs;
$langs->loadLangs(array("boxes", "sendings", "orders"));
$this->max = $max;
include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
$supplierorderstatic=new CommandeFournisseur($db);
$supplierorderstatic=new CommandeFournisseur($this->db);
include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
$thirdpartytmp = new Fournisseur($db);
$thirdpartytmp = new Fournisseur($this->db);
$this->info_box_head = array('text' => $langs->trans("BoxTitleSupplierOrdersAwaitingReception", $max));
if ($user->rights->fournisseur->commande->lire)
{
$sql = "SELECT s.nom as name, s.rowid as socid,";
$sql.= " s.code_client, s.code_fournisseur,";
$sql.= " s.code_client, s.code_fournisseur, s.email,";
$sql.= " s.logo,";
$sql.= " c.rowid, c.ref, c.tms, c.date_commande, c.date_livraison, ";
$sql.= " c.total_ht,";
@ -102,19 +102,19 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes
if ($user->socid) $sql.= " AND s.rowid = ".$user->socid;
if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql.= " ORDER BY c.date_commande DESC, c.ref DESC ";
else $sql.= " ORDER BY c.date_livraison ASC, c.fk_statut ASC ";
$sql.= $db->plimit($max, 0);
$sql.= $this->db->plimit($max, 0);
$result = $db->query($sql);
$result = $this->db->query($sql);
if ($result)
{
$num = $db->num_rows($result);
$num = $this->db->num_rows($result);
$line = 0;
while ($line < $num) {
$objp = $db->fetch_object($result);
$date=$db->jdate($objp->date_commande);
$date_livraison=$db->jdate($objp->date_livraison);
$datem=$db->jdate($objp->tms);
$objp = $this->db->fetch_object($result);
$date=$this->db->jdate($objp->date_commande);
$date_livraison=$this->db->jdate($objp->date_livraison);
$datem=$this->db->jdate($objp->tms);
$supplierorderstatic->date_livraison = $date_livraison;
$supplierorderstatic->statut = $objp->fk_statut;
@ -124,6 +124,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes
$thirdpartytmp->id = $objp->socid;
$thirdpartytmp->name = $objp->name;
$thirdpartytmp->email = $objp->email;
$thirdpartytmp->fournisseur = 1;
$thirdpartytmp->code_fournisseur = $objp->code_fournisseur;
$thirdpartytmp->logo = $objp->logo;
@ -165,12 +166,12 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes
'text' => $langs->trans("NoSupplierOrder"),
);
$db->free($result);
$this->db->free($result);
} else {
$this->info_box_contents[0][] = array(
'td' => '',
'maxlength'=>500,
'text' => ($db->error().' sql='.$sql),
'text' => ($this->db->error().' sql='.$sql),
);
}
}

View File

@ -129,19 +129,32 @@ class CMailFile
* @param string $css Css option
* @param string $trackid Tracking string (contains type and id of related element)
* @param string $moreinheader More in header. $moreinheader must contains the "\r\n" (TODO not supported for other MAIL_SEND_MODE different than 'phpmail' and 'smtps' for the moment)
* @param string $sendcontext 'standard', 'emailing', ... (used to define with sending mode and parameters to use)
* @param string $sendcontext 'standard', 'emailing', ... (used to define which sending mode and parameters to use)
* @param string $replyto Reply-to email (will be set to same value than From by default if not provided)
*/
public function __construct($subject, $to, $from, $msg, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = 0, $errors_to = '', $css = '', $trackid = '', $moreinheader = '', $sendcontext = 'standard', $replyto = '')
{
global $conf, $dolibarr_main_data_root;
$this->subject = $subject;
$this->addr_to = $to;
$this->addr_from = $from;
$this->msg = $msg;
$this->filename_list = $filename_list;
$this->mimetype_list = $mimetype_list;
$this->mimefilename_list = $mimefilename_list;
$this->addr_cc = $addr_cc;
$this->addr_bcc = $addr_bcc;
$this->deliveryreceipt = $deliveryreceipt;
if (empty($replyto)) $replyto = $from;
$this->reply_to = $replyto;
$this->errors_to = $errors_to;
$this->trackid = $trackid;
$this->sendcontext = $sendcontext;
$this->filename_list = $filename_list;
$this->mimetype_list = $mimetype_list;
$this->mimefilename_list = $mimefilename_list;
if (empty($replyto)) $replyto=$from;
// Define this->sendmode
$this->sendmode = '';
@ -262,16 +275,6 @@ class CMailFile
$files_encoded = "";
// Define smtp_headers
$this->subject = $subject;
$this->addr_from = $from;
$this->reply_to = $replyto;
$this->errors_to = $errors_to;
$this->addr_to = $to;
$this->addr_cc = $addr_cc;
$this->addr_bcc = $addr_bcc;
$this->deliveryreceipt = $deliveryreceipt;
$this->trackid = $trackid;
$smtp_headers = $this->write_smtpheaders();
if (! empty($moreinheader)) $smtp_headers.=$moreinheader; // $moreinheader contains the \r\n

View File

@ -6595,10 +6595,19 @@ abstract class CommonObject
$out .= '<td class="';
//$out .= "titlefield";
//if (GETPOST('action', 'none') == 'create') $out.='create';
if ($mode != 'view' && ! empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired';
$out .= '">';
if (! empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $extrafields->attributes[$this->table_element]['help'][$key]);
else $out .= $labeltoshow;
// BUG #11554 : For public page, use red dot for required fields, instead of bold label
$context = isset($params["context"]) ? $params["context"] : "none";
if ($context=="public") { // Public page : red dot instead of bold ble characters
$out .= '">';
if (! empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $extrafields->attributes[$this->table_element]['help'][$key]);
else $out .= $labeltoshow;
if ($mode != 'view' && ! empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= '&nbsp;<font color="red">*</font>';
} else {
if ($mode != 'view' && ! empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired';
$out .= '">';
if (! empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $extrafields->attributes[$this->table_element]['help'][$key]);
else $out .= $labeltoshow;
}
$out .= '</td>';
$html_id = !empty($this->id) ? $this->element.'_extras_'.$key.'_'.$this->id : '';

View File

@ -1555,7 +1555,7 @@ class ExtraFields
{
$param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
$showempty=(($required && $default != '')?0:1);
$out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
$out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', $morecss);
}
elseif ($type == 'password')
{

View File

@ -7509,7 +7509,7 @@ class Form
*/
public function showFilterAndCheckAddButtons($addcheckuncheckall = 0, $cssclass = 'checkforaction', $calljsfunction = 0)
{
$out.=$this->showFilterButtons();
$out=$this->showFilterButtons();
if ($addcheckuncheckall)
{
$out.=$this->showCheckAddButtons($cssclass, $calljsfunction);

View File

@ -981,7 +981,7 @@ class FormTicket
include_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php';
$uselocalbrowser = true;
$doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 140, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
$doleditor = new DolEditor('mail_intro', $mail_intro, '100%', 90, 'dolibarr_details', '', false, true, $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_2, 70);
$doleditor->Create();
print '</td><td align="center">';

View File

@ -541,7 +541,12 @@ class Notify
'',
'',
0,
-1
-1,
'',
'',
'',
'',
'notification'
);
if ($mailfile->sendfile())
@ -769,7 +774,12 @@ class Notify
'',
'',
0,
1
1,
'',
'',
'',
'',
'notification'
);
if ($mailfile->sendfile())

View File

@ -1568,7 +1568,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon = '', $noprin
$out.='</td>';
// Author of event
$out.='<td class="tdoverflowmax100">';
$out.='<td class="tdoverflowmax200">';
//$userstatic->id=$histo[$key]['userid'];
//$userstatic->login=$histo[$key]['login'];
//$out.=$userstatic->getLoginUrl(1);

View File

@ -3036,36 +3036,43 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
$moreatt = str_replace('class="'.$reg[1].'"', '', $moreatt);
}
} else {
$pictowithoutext = preg_replace('/(\.png|\.gif|\.svg)$/', '', $picto);
$pictowithouttext = preg_replace('/(\.png|\.gif|\.svg)$/', '', $picto);
//if (in_array($picto, array('switch_off', 'switch_on', 'off', 'on')))
if (empty($srconly) && in_array($pictowithoutext, array(
'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'note', 'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
'note', 'setup', 'sign-out', 'split', 'switch_off', 'switch_on', 'tools', 'unlink', 'uparrow', '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected',
if (empty($srconly) && in_array($pictowithouttext, array(
'bank', 'close_title', 'delete', 'edit', 'ellipsis-h', 'filter', 'grip', 'grip_title', 'list', 'listlight', 'note',
'object_list','object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser',
'off', 'on', 'play', 'playdisabled', 'printer', 'resize',
'note', 'setup', 'sign-out', 'split', 'switch_off', 'switch_on', 'tools', 'unlink', 'uparrow', '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected',
'jabber', 'skype', 'twitter', 'facebook', 'linkedin', 'instagram', 'snapchat', 'youtube', 'google-plus-g','whatsapp',
'chevron-left','chevron-right','chevron-down','chevron-top'
'chevron-left','chevron-right','chevron-down','chevron-top',
'home', 'companies', 'products', 'commercial', 'invoicing', 'accountancy', 'project', 'hrm', 'members', 'ticket', 'generic'
)
)) {
$fa='fa';
$fa='fa';
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fa='fas';
$fakey = $pictowithoutext;
$facolor = ''; $fasize = '';
$fakey = $pictowithouttext;
$facolor = ''; $fasize = '';
if ($pictowithoutext == 'setup') {
$fakey = 'fa-cog';
$fasize = '1.4em';
}
elseif ($pictowithoutext == 'switch_off') {
$fakey = 'fa-toggle-off';
$arrayconvpictotofa = array(
'setup'=>'cog', 'companies'=>'building', 'products'=>'box_open', 'commercial'=>'box-tie', 'invoicing'=>'file-invoice', 'accountancy'=>'coins', 'project'=>'project-diagram',
'hrm'=>'umbrella-beach', 'members'=>'user-friends', 'ticket'=>'sticky-note', 'generic'=>'folder-open',
'switch_off'=>'toggle-off', 'switch_on'=>'toggle-on',
'bank'=>'bank', 'close_title'=>'window-close', 'delete'=>'trash', 'edit'=>'pencil', 'filter'=>'filter', 'split'=>'code-fork',
'object_list'=>'list-alt','object_calendar'=>'calendar-alt', 'object_calendarweek'=>'calendar-week', 'object_calendarmonth'=>'calendar-alt', 'object_calendarday'=>'calendar-day', 'object_calendarperuser'=>'table'
);
if ($pictowithouttext == 'switch_off') {
$facolor = '#999';
$fasize = '2em';
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
}
elseif ($pictowithoutext == 'switch_on') {
$fakey = 'fa-toggle-on';
elseif ($pictowithouttext == 'switch_on') {
$facolor = '#227722';
$fasize = '2em';
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
}
elseif ($pictowithoutext == 'off') {
elseif ($pictowithouttext == 'off') {
$fakey = 'fa-square-o';
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5))
{
@ -3074,7 +3081,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
}
$fasize = '1.3em';
}
elseif ($pictowithoutext == 'on') {
elseif ($pictowithouttext == 'on') {
$fakey = 'fa-check-square-o';
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5))
{
@ -3083,44 +3090,38 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
}
$fasize = '1.3em';
}
elseif ($pictowithoutext == 'bank') {
$fakey = 'fa-bank';
elseif ($pictowithouttext == 'bank') {
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
$facolor = '#444';
}
elseif ($pictowithoutext == 'close_title') {
$fakey = 'fa-window-close';
}
elseif ($pictowithoutext == 'delete') {
$fakey = 'fa-trash';
elseif ($pictowithouttext == 'delete') {
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
$facolor = '#444';
}
elseif ($pictowithoutext == 'edit') {
$fakey = 'fa-pencil';
elseif ($pictowithouttext == 'edit') {
$facolor = '#444';
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fakey = 'fa-pencil-alt';
}
elseif ($pictowithoutext == 'filter') {
$fakey = 'fa-'.$pictowithoutext;
}
elseif ($pictowithoutext == 'grip_title' || $pictowithoutext == 'grip') {
elseif ($pictowithouttext == 'grip_title' || $pictowithouttext == 'grip') {
$fakey = 'fa-arrows';
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fakey = 'fa-arrows-alt';
}
elseif ($pictowithoutext == 'listlight') {
elseif ($pictowithouttext == 'listlight') {
$fakey = 'fa-download';
$facolor = '#999';
$marginleftonlyshort=1;
}
elseif ($pictowithoutext == 'printer') {
elseif ($pictowithouttext == 'printer') {
$fakey = 'fa-print';
$fasize = '1.2em';
$facolor = '#444';
}
elseif ($pictowithoutext == 'resize') {
elseif ($pictowithouttext == 'resize') {
$fakey = 'fa-crop';
$facolor = '#444';
}
elseif ($pictowithoutext == 'note') {
elseif ($pictowithouttext == 'note') {
$fakey = 'fa-sticky-note-o';
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5))
{
@ -3129,45 +3130,58 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $
$facolor = '#999';
$marginleftonlyshort=1;
}
elseif ($pictowithoutext == 'uparrow') {
elseif ($pictowithouttext == 'uparrow') {
$fakey = 'fa-mail-forward';
$facolor = '#555';
}
elseif (in_array($pictowithoutext, array('1uparrow', '1downarrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected'))) {
elseif (in_array($pictowithouttext, array('1uparrow', '1downarrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected'))) {
$convertarray=array('1uparrow'=>'caret-up', '1downarrow'=>'caret-down', '1leftarrow'=>'caret-left', '1rightarrow'=>'caret-right', '1uparrow_selected'=>'caret-up', '1downarrow_selected'=>'caret-down', '1leftarrow_selected'=>'caret-left', '1rightarrow_selected'=>'caret-right');
$fakey = 'fa-'.$convertarray[$pictowithoutext];
if (preg_match('/selected/', $pictowithoutext)) $facolor = '#888';
$fakey = 'fa-'.$convertarray[$pictowithouttext];
if (preg_match('/selected/', $pictowithouttext)) $facolor = '#888';
$marginleftonlyshort = 1;
}
elseif ($pictowithoutext == 'sign-out') {
elseif ($pictowithouttext == 'sign-out') {
$fakey = 'fa-sign-out';
$marginleftonlyshort=0;
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fakey = 'fa-sign-out-alt';
}
elseif ($pictowithoutext == 'unlink') {
elseif ($pictowithouttext == 'unlink') {
$fakey = 'fa-chain-broken';
$facolor = '#555';
}
elseif ($pictowithoutext == 'playdisabled') {
elseif ($pictowithouttext == 'playdisabled') {
$fakey = 'fa-play';
$facolor = '#ccc';
}
elseif ($pictowithoutext == 'play') {
elseif ($pictowithouttext == 'play') {
$fakey = 'fa-play';
$facolor = '#444';
}
elseif ($pictowithoutext == 'jabber') {
elseif ($pictowithouttext == 'jabber') {
$fakey = 'fa-comment-o';
}
<<<<<<< HEAD
elseif (in_array($pictowithoutext, array('skype', 'twitter', 'facebook', 'linkedin', 'instagram','snapchat','youtube','google-plus-g','whatsapp'))) {
$fakey = 'fa-'.$pictowithoutext;
=======
elseif (in_array($pictowithouttext, array('skype', 'twitter', 'facebook', 'linkedin'))) {
$fakey = 'fa-'.$pictowithouttext;
>>>>>>> upstream/develop
if (empty($conf->global->MAIN_DISABLE_FONT_AWESOME_5)) $fa = 'fab';
}
elseif ($pictowithoutext == 'split') {
$fakey = 'fa-code-fork';
// Img for type of views
elseif (in_array($pictowithouttext, array('object_list', 'object_calendar', 'object_calendarweek', 'object_calendarmonth', 'object_calendarday', 'object_calendarperuser'))) {
$fakey = 'imgforviewmode fa-'.$arrayconvpictotofa[$pictowithouttext];
$marginleftonlyshort=0;
}
elseif (! empty($arrayconvpictotofa[$pictowithouttext]))
{
$fakey = 'fa-'.$arrayconvpictotofa[$pictowithouttext];
$facolor = '#444';
$marginleftonlyshort=0;
}
else {
$fakey = 'fa-'.$pictowithoutext;
$fakey = 'fa-'.$pictowithouttext;
$facolor = '#444';
$marginleftonlyshort=0;
}
@ -4099,7 +4113,7 @@ function print_titre($title)
* @return void
* @deprecated Use print load_fiche_titre instead
*/
function print_fiche_titre($title, $mesg = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $id = '')
function print_fiche_titre($title, $mesg = '', $picto = 'generic', $pictoisfullpath = 0, $id = '')
{
print load_fiche_titre($title, $mesg, $picto, $pictoisfullpath, $id);
}
@ -4117,13 +4131,13 @@ function print_fiche_titre($title, $mesg = '', $picto = 'title_generic.png', $pi
* @return string
* @see print_barre_liste()
*/
function load_fiche_titre($titre, $morehtmlright = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $id = '', $morecssontable = '', $morehtmlcenter = '')
function load_fiche_titre($titre, $morehtmlright = '', $picto = 'generic', $pictoisfullpath = 0, $id = '', $morecssontable = '', $morehtmlcenter = '')
{
global $conf;
$return='';
if ($picto == 'setup') $picto='title_generic.png';
if ($picto == 'setup') $picto='generic';
$return.= "\n";
$return.= '<table '.($id?'id="'.$id.'" ':'').'class="centpercent notopnoleftnoright'.($morecssontable?' '.$morecssontable:'').'" style="margin-bottom: 6px;"><tr>'; // maring bottom must be same than into print_barre_list
@ -4165,7 +4179,7 @@ function load_fiche_titre($titre, $morehtmlright = '', $picto = 'title_generic.p
* @param int $hidenavigation Force to hide all navigation tools
* @return void
*/
function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', $sortorder = '', $morehtmlcenter = '', $num = -1, $totalnboflines = '', $picto = 'title_generic.png', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limit = -1, $hideselectlimit = 0, $hidenavigation = 0)
function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', $sortorder = '', $morehtmlcenter = '', $num = -1, $totalnboflines = '', $picto = 'generic', $pictoisfullpath = 0, $morehtmlright = '', $morecss = '', $limit = -1, $hideselectlimit = 0, $hidenavigation = 0)
{
global $conf,$langs;
@ -4174,7 +4188,7 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '',
$totalnboflines=abs($totalnboflines);
if ($picto == 'setup') $picto='title_setup.png';
if (($conf->browser->name == 'ie') && $picto=='title_generic.png') $picto='title.gif';
if (($conf->browser->name == 'ie') && $picto=='generic') $picto='title.gif';
if ($limit < 0) $limit = $conf->liste_limit;
if ($savlimit != 0 && (($num > $limit) || ($num == -1) || ($limit == 0)))
{
@ -8261,7 +8275,7 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url =
*
* @param string $label label of button
* @param string $helpText optional : content for help tooltip
* @param string $iconClass class for icon element
* @param string $iconClass class for icon element (Example: 'fa fa-file')
* @param string $url the url for link
* @param string $id attribute id of button
* @param int $status 0 no user rights, 1 active, -1 Feature Disabled, -2 disable Other reason use helpText as tooltip
@ -8277,12 +8291,12 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
return '';
}
$class = 'btnTitle' ;
$class = 'btnTitle';
// hidden conf keep during button transition TODO: remove this block
if(empty($conf->global->MAIN_USE_NEW_TITLE_BUTTON)){
if (empty($conf->global->MAIN_USE_NEW_TITLE_BUTTON)) {
$class = 'butActionNew';
}
if (! empty($params['morecss'])) $class.=' '.$params['morecss'];
$attr=array(
'class' => $class
@ -8348,9 +8362,9 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u
$TCompiledAttr[] = $key.'="'.$value.'"';
}
$compiledAttributes = !empty($TCompiledAttr)?implode(' ', $TCompiledAttr):'';
$compiledAttributes = (empty($TCompiledAttr) ? '' : implode(' ', $TCompiledAttr));
$tag = !empty($attr['href'])?'a':'span';
$tag = (empty($attr['href']) ? 'span' : 'a');
$button ='<'.$tag.' '.$compiledAttributes.' >';

View File

@ -108,7 +108,21 @@ function ticket_prepare_head($object)
// History
$head[$h][0] = DOL_URL_ROOT.'/ticket/agenda.php?track_id=' . $object->track_id;
$ticketViewType = "messaging";
if(empty($_SESSION['ticket-view-type'])){
$_SESSION['ticket-view-type'] = $ticketViewType;
}
else{
$ticketViewType = $_SESSION['ticket-view-type'];
}
if($ticketViewType == "messaging"){
$head[$h][0] = DOL_URL_ROOT.'/ticket/messaging.php?track_id=' . $object->track_id;
}
else{
// $ticketViewType == "list"
$head[$h][0] = DOL_URL_ROOT.'/ticket/agenda.php?track_id=' . $object->track_id;
}
$head[$h][1] = $langs->trans('Events');
if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))
{
@ -187,3 +201,612 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $
print '<div class="ticketlargemargin">';
}
/**
* Show html area with actions for ticket messaging.
* Note: Global parameter $param must be defined.
*
* @param Conf $conf Object conf
* @param Translate $langs Object langs
* @param DoliDB $db Object db
* @param mixed $filterobj Filter on object Adherent|Societe|Project|Product|CommandeFournisseur|Dolresource|Ticket|... to list events linked to an object
* @param Contact $objcon Filter on object contact to filter events on a contact
* @param int $noprint Return string but does not output it
* @param string $actioncode Filter on actioncode
* @param string $donetodo Filter on event 'done' or 'todo' or ''=nofilter (all).
* @param array $filters Filter on other fields
* @param string $sortfield Sort field
* @param string $sortorder Sort order
* @return string|void Return html part or void if noprint is 1
*/
function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $noprint = 0, $actioncode = '', $donetodo = 'done', $filters = array(), $sortfield = 'a.datep,a.id', $sortorder = 'DESC')
{
global $user, $conf;
global $form;
global $param, $massactionbutton;
dol_include_once('/comm/action/class/actioncomm.class.php');
// Check parameters
if (! is_object($filterobj) && ! is_object($objcon)) dol_print_error('', 'BadParameter');
$out='';
$histo=array();
$numaction = 0 ;
$now=dol_now('tzuser');
// Open DSI -- Fix order by -- Begin
$sortfield_list = explode(',', $sortfield);
$sortfield_label_list = array('a.id' => 'id', 'a.datep' => 'dp', 'a.percent' => 'percent');
$sortfield_new_list = array();
foreach ($sortfield_list as $sortfield_value) {
$sortfield_new_list[] = $sortfield_label_list[trim($sortfield_value)];
}
$sortfield_new = implode(',', $sortfield_new_list);
if (! empty($conf->agenda->enabled))
{
// Recherche histo sur actioncomm
if (is_object($objcon) && $objcon->id > 0) {
$sql = "SELECT DISTINCT a.id, a.label as label,";
}
else
{
$sql = "SELECT a.id, a.label as label,";
}
$sql.= " a.datep as dp,";
$sql.= " a.note as message,";
$sql.= " a.datep2 as dp2,";
$sql.= " a.percent as percent, 'action' as type,";
$sql.= " a.fk_element, a.elementtype,";
$sql.= " a.fk_contact,";
$sql.= " c.code as acode, c.libelle as alabel, c.picto as apicto,";
$sql.= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname";
if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname";
elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname";
elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", o.ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql.= ", o.ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') $sql.= ", o.ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') $sql.= ", o.ref";
$sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_action";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id";
$force_filter_contact = false;
if (is_object($objcon) && $objcon->id > 0) {
$force_filter_contact = true;
$sql.= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as r ON a.id = r.fk_actioncomm";
$sql.= " AND r.element_type = '" . $db->escape($objcon->table_element) . "' AND r.fk_element = " . $objcon->id;
}
if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid";
elseif (is_object($filterobj) && get_class($filterobj) == 'Dolresource') {
$sql.= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as er";
$sql.= " ON er.resource_type = 'dolresource'";
$sql.= " AND er.element_id = a.id";
$sql.= " AND er.resource_id = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m";
elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o";
elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", ".MAIN_DB_PREFIX."product as o";
elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql.= ", ".MAIN_DB_PREFIX."ticket as o";
elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') $sql.= ", ".MAIN_DB_PREFIX."bom_bom as o";
elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') $sql.= ", ".MAIN_DB_PREFIX."contrat as o";
$sql.= " WHERE a.entity IN (".getEntity('agenda').")";
if ($force_filter_contact === false) {
if (is_object($filterobj) && in_array(get_class($filterobj), array('Societe', 'Client', 'Fournisseur')) && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id;
elseif (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) $sql.= " AND a.fk_project = ".$filterobj->id;
elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent')
{
$sql.= " AND a.fk_element = m.rowid AND a.elementtype = 'member'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur')
{
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'Product')
{
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket')
{
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'ticket'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'BOM')
{
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'bom'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat')
{
$sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'contract'";
if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id;
}
}
// Condition on actioncode
if (! empty($actioncode))
{
if (empty($conf->global->AGENDA_USE_EVENT_TYPE))
{
if ($actioncode == 'AC_NON_AUTO') $sql.= " AND c.type != 'systemauto'";
elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND c.type = 'systemauto'";
else
{
if ($actioncode == 'AC_OTH') $sql.= " AND c.type != 'systemauto'";
elseif ($actioncode == 'AC_OTH_AUTO') $sql.= " AND c.type = 'systemauto'";
}
}
else
{
if ($actioncode == 'AC_NON_AUTO') $sql.= " AND c.type != 'systemauto'";
elseif ($actioncode == 'AC_ALL_AUTO') $sql.= " AND c.type = 'systemauto'";
else $sql.= " AND c.code = '".$db->escape($actioncode)."'";
}
}
if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
if (is_array($filters) && $filters['search_agenda_label']) $sql.= natural_search('a.label', $filters['search_agenda_label']);
}
// Add also event from emailings. TODO This should be replaced by an automatic event ? May be it's too much for very large emailing.
if (! empty($conf->mailing->enabled) && ! empty($objcon->email)
&& (empty($actioncode) || $actioncode == 'AC_OTH_AUTO' || $actioncode == 'AC_EMAILING'))
{
$langs->load("mails");
$sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type";
$sql2.= ", '' as fk_element, '' as elementtype, '' as contact_id";
$sql2.= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto";
$sql2.= ", u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action
if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql2.= ", '' as lastname, '' as firstname";
elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql2.= ", '' as lastname, '' as firstname";
elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql2.= ", '' as ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'Product') $sql2.= ", '' as ref";
elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') $sql2.= ", '' as ref";
$sql2.= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u";
$sql2.= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email.
$sql2.= " AND mc.statut = 1";
$sql2.= " AND u.rowid = m.fk_user_valid";
$sql2.= " AND mc.fk_mailing=m.rowid";
}
if (!empty($sql) && !empty($sql2)) {
$sql = $sql . " UNION " . $sql2;
} elseif (empty($sql) && !empty($sql2)) {
$sql = $sql2;
}
//TODO Add limit in nb of results
$sql.= $db->order($sortfield_new, $sortorder);
dol_syslog("company.lib::show_actions_done", LOG_DEBUG);
$resql=$db->query($sql);
if ($resql)
{
$i = 0 ;
$num = $db->num_rows($resql);
while ($i < $num)
{
$obj = $db->fetch_object($resql);
if ($obj->type == 'action') {
$contactaction = new ActionComm($db);
$contactaction->id=$obj->id;
$result = $contactaction->fetchResources();
if ($result<0) {
dol_print_error($db);
setEventMessage("company.lib::show_actions_done Error fetch ressource", 'errors');
}
//if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
//elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
$tododone='';
if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) $tododone='todo';
$histo[$numaction]=array(
'type'=>$obj->type,
'tododone'=>$tododone,
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo,
'contact_id'=>$obj->fk_contact,
'socpeopleassigned' => $contactaction->socpeopleassigned,
'lastname'=>$obj->lastname,
'firstname'=>$obj->firstname,
'fk_element'=>$obj->fk_element,
'elementtype'=>$obj->elementtype,
// Type of event
'acode'=>$obj->acode,
'alabel'=>$obj->alabel,
'libelle'=>$obj->alabel, // deprecated
'apicto'=>$obj->apicto
);
} else {
$histo[$numaction]=array(
'type'=>$obj->type,
'tododone'=>'done',
'id'=>$obj->id,
'datestart'=>$db->jdate($obj->dp),
'dateend'=>$db->jdate($obj->dp2),
'note'=>$obj->label,
'message'=>$obj->message,
'percent'=>$obj->percent,
'acode'=>$obj->acode,
'userid'=>$obj->user_id,
'login'=>$obj->user_login,
'userfirstname'=>$obj->user_firstname,
'userlastname'=>$obj->user_lastname,
'userphoto'=>$obj->user_photo
);
}
$numaction++;
$i++;
}
}
else
{
dol_print_error($db);
}
if (! empty($conf->agenda->enabled) || (! empty($conf->mailing->enabled) && ! empty($objcon->email)))
{
$delay_warning=$conf->global->MAIN_DELAY_ACTIONS_TODO*24*60*60;
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
$formactions=new FormActions($db);
$actionstatic=new ActionComm($db);
$userstatic=new User($db);
$contactstatic = new Contact($db);
$userGetNomUrlCache = array();
$out.='<div class="filters-container" >';
$out.='<form name="listactionsfilter" class="listactionsfilter" action="' . $_SERVER["PHP_SELF"] . '" method="POST">';
if ($objcon && get_class($objcon) == 'Contact' &&
(is_null($filterobj) || get_class($filterobj) == 'Societe'))
{
$out.='<input type="hidden" name="id" value="'.$objcon->id.'" />';
}
else
{
$out.='<input type="hidden" name="id" value="'.$filterobj->id.'" />';
}
if ($filterobj && get_class($filterobj) == 'Societe') $out.='<input type="hidden" name="socid" value="'.$filterobj->id.'" />';
$out.="\n";
$out.='<div class="div-table-responsive-no-min">';
$out.='<table class="noborder" width="100%">';
$out.='<tr class="liste_titre">';
$out.='<td class="liste_titre">';
if($sortorder === 'desc') {
$sortUrl = $_SERVER["PHP_SELF"] . '?sortfield=a.datep&sortorder=asc' . $param;
$out .= dolGetButtonTitle($langs->trans('Date'), $langs->trans('OrderByDateAsc'), 'fa fa-sort-numeric-down', $sortUrl, '', 1);
}
else{
$sortUrl = $_SERVER["PHP_SELF"] . '?sortfield=a.datep&sortorder=desc' . $param;
$out .= dolGetButtonTitle($langs->trans('Date'), $langs->trans('OrderByDateDesc'), 'fa fa-sort-numeric-down-alt', $sortUrl, '', 1);
}
$out.='</td>';
$out.='<td class="liste_titre"><strong>'.$langs->trans("Search").' : </strong></td>';
if ($donetodo)
{
$out.='<td class="liste_titre"></td>';
}
$out.='<td class="liste_titre">'.$langs->trans("Type").' ';
$out.=$formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:-1, 0, 0, 1);
$out.='</td>';
$out.='<td class="liste_titre maxwidth100onsmartphone">';
$out.=$langs->trans("Label").' ';
$out.='<input type="text" class="maxwidth100onsmartphone" name="search_agenda_label" value="'.$filters['search_agenda_label'].'">';
$out.='</td>';
$out.='<td class="liste_titre" align="middle">';
$searchpicto=$form->showFilterAndCheckAddButtons($massactionbutton?1:0, 'checkforselect', 1);
$out.=$searchpicto;
$out.='</td>';
$out.='</tr>';
$out.='</table>';
$out.='</form>';
$out.='</div>';
$out.="\n";
$out.='<ul class="timeline">';
if ($donetodo)
{
$tmp='';
if (get_class($filterobj) == 'Societe') $tmp.='<a href="'.DOL_URL_ROOT.'/comm/action/list.php?socid='.$filterobj->id.'&amp;status=done">';
$tmp.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : '');
$tmp.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : '');
$tmp.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : '');
//$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort");
if (get_class($filterobj) == 'Societe') $tmp.='</a>';
$out.=getTitleFieldOfList($tmp);
}
//require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
//$caction=new CActionComm($db);
//$arraylist=$caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0), '', 1);
$actualCycleDate = false;
foreach ($histo as $key=>$value)
{
$actionstatic->fetch($histo[$key]['id']); // TODO Do we need this, we already have a lot of data of line into $histo
$actionstatic->type_picto=$histo[$key]['apicto'];
$actionstatic->type_code=$histo[$key]['acode'];
$url = DOL_URL_ROOT.'/comm/action/card.php?id='.$histo[$key]['id'];
$tmpa=dol_getdate($histo[$key]['datestart'], false);
if($actualCycleDate !== $tmpa['year'].'-'.$tmpa['yday']){
$actualCycleDate = $tmpa['year'].'-'.$tmpa['yday'];
$out.='<!-- timeline time label -->';
$out.='<li class="time-label">';
$out.='<span class="timeline-badge-date">';
$out.= dol_print_date($histo[$key]['datestart'], 'daytext', 'tzserver', $langs);
$out.='</span>';
$out.='</li>';
$out.='<!-- /.timeline-label -->';
}
$out.='<!-- timeline item -->'."\n";
$out.='<li class="timeline-code-'.strtolower($actionstatic->code).'">';
$out.='<!-- timeline icon -->'."\n";
$iconClass = 'fa fa-comments';
$img_picto = '';
$colorClass = '';
$pictoTitle = '';
if ($histo[$key]['percent']==-1) {
$colorClass = 'timeline-icon-not-applicble';
$pictoTitle = $langs->trans('StatusNotApplicable');
}
elseif ($histo[$key]['percent']==0) {
$colorClass = 'timeline-icon-todo';
$pictoTitle = $langs->trans('StatusActionToDo') . ' (0%)';
}
elseif ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100){
$colorClass = 'timeline-icon-in-progress';
$pictoTitle = $langs->trans('StatusActionInProcess').' ('.$histo[$key]['percent'].'%)';
}
elseif ($histo[$key]['percent'] >= 100){
$colorClass = 'timeline-icon-done';
$pictoTitle = $langs->trans('StatusActionDone').' (100%)';
}
if($actionstatic->code == 'AC_TICKET_CREATE'){
$iconClass = 'fa fa-ticket';
}
elseif($actionstatic->code == 'AC_TICKET_MODIFY'){
$iconClass = 'fa fa-pencil';
}
elseif($actionstatic->code == 'TICKET_MSG'){
$iconClass = 'fa fa-comments';
}
elseif($actionstatic->code == 'TICKET_MSG_PRIVATE'){
$iconClass = 'fa fa-mask';
}
elseif (!empty($conf->global->AGENDA_USE_EVENT_TYPE))
{
if ($actionstatic->type_picto) $img_picto = img_picto('', $actionstatic->type_picto);
else {
if ($actionstatic->type_code == 'AC_RDV') $iconClass = 'fa fa-handshake';
elseif ($actionstatic->type_code == 'AC_TEL') $iconClass = 'fa fa-phone';
elseif ($actionstatic->type_code == 'AC_FAX') $iconClass = 'fa fa-fax';
elseif ($actionstatic->type_code == 'AC_EMAIL') $iconClass = 'fa fa-envelope';
elseif ($actionstatic->type_code == 'AC_INT') $iconClass = 'fa fa-shipping-fast';
elseif ($actionstatic->type_code == 'AC_OTH_AUTO') $iconClass = 'fa fa-robot';
elseif (! preg_match('/_AUTO/', $actionstatic->type_code)) $iconClass = 'fa fa-robot';
}
}
$out.='<i class="'.$iconClass .' '.$colorClass.'" title="'.$pictoTitle .'">'.$img_picto.'</i>'."\n";
$out.='<div class="timeline-item">'."\n";
$out.='<span class="timeline-header-action">';
if (isset($histo[$key]['type']) && $histo[$key]['type']=='mailing') {
$out.='<a class="timeline-btn" href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$histo[$key]['id'].'">'.img_object($langs->trans("ShowEMailing"), "email").' ';
$out.=$histo[$key]['id'];
$out.='</a> ';
} else {
$out.=$actionstatic->getNomUrl(1, -1).' ';
}
// if ($user->rights->agenda->allactions->read || $actionstatic->authorid == $user->id)
// {
// $out.='<a href="'.$url.'" class="timeline-btn" title="'.$langs->trans('Show').'" ><i class="fa fa-calendar" ></i>'.$langs->trans('Show').'</a>';
// }
if ($user->rights->agenda->allactions->create ||
(($actionstatic->authorid == $user->id || $actionstatic->userownerid == $user->id) && $user->rights->agenda->myactions->create))
{
$out.='<a class="timeline-btn" href="' . DOL_MAIN_URL_ROOT. '/comm/action/card.php?action=edit&id='.$actionstatic->id.'"><i class="fa fa-pencil" title="'.$langs->trans("Modify").'" ></i></a>';
}
$out.='</span>';
// Date
$out.='<span class="time"><i class="fa fa-clock-o"></i> ';
$out.=dol_print_date($histo[$key]['datestart'], 'dayhour');
if ($histo[$key]['dateend'] && $histo[$key]['dateend'] != $histo[$key]['datestart'])
{
$tmpa=dol_getdate($histo[$key]['datestart'], true);
$tmpb=dol_getdate($histo[$key]['dateend'], true);
if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) $out.='-'.dol_print_date($histo[$key]['dateend'], 'hour');
else $out.='-'.dol_print_date($histo[$key]['dateend'], 'dayhour');
}
$late=0;
if ($histo[$key]['percent'] == 0 && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1;
if ($histo[$key]['percent'] == 0 && ! $histo[$key]['datestart'] && $histo[$key]['dateend'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1;
if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && $histo[$key]['dateend'] && $histo[$key]['dateend'] < ($now - $delay_warning)) $late=1;
if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && ! $histo[$key]['dateend'] && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1;
if ($late) $out.=img_warning($langs->trans("Late")).' ';
$out.="</span>\n";
// Ref
$out.='<h3 class="timeline-header">';
// Author of event
$out.='<span class="messaging-author">';
if ($histo[$key]['userid'] > 0)
{
if(!isset($userGetNomUrlCache[$histo[$key]['userid']])){ // is in cache ?
$userstatic->fetch($histo[$key]['userid']);
$userGetNomUrlCache[$histo[$key]['userid']] = $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, 'firstelselast', '');
}
$out.= $userGetNomUrlCache[$histo[$key]['userid']];
}
$out.='</span>';
// Title
$out .= ' <span class="messaging-title">';
if($actionstatic->code == 'TICKET_MSG') {
$out .= $langs->trans('TicketNewMessage');
}
elseif($actionstatic->code == 'TICKET_MSG_PRIVATE') {
$out .= $langs->trans('TicketNewMessage').' <em>('.$langs->trans('Private').')</em>';
}else{
if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'action') {
$transcode = $langs->trans("Action" . $histo[$key]['acode']);
$libelle = ($transcode != "Action" . $histo[$key]['acode'] ? $transcode : $histo[$key]['alabel']);
$libelle = $histo[$key]['note'];
$actionstatic->id = $histo[$key]['id'];
$out .= dol_trunc($libelle, 120);
}
if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'mailing') {
$out .= '<a href="' . DOL_URL_ROOT . '/comm/mailing/card.php?id=' . $histo[$key]['id'] . '">' . img_object($langs->trans("ShowEMailing"), "email") . ' ';
$transcode = $langs->trans("Action" . $histo[$key]['acode']);
$libelle = ($transcode != "Action" . $histo[$key]['acode'] ? $transcode : 'Send mass mailing');
$out .= dol_trunc($libelle, 120);
}
}
$out .= '</span>';
$out.='</h3>';
if (! empty($histo[$key]['message'])
&& $actionstatic->code != 'AC_TICKET_CREATE'
&& $actionstatic->code != 'AC_TICKET_MODIFY'
)
{
$out.='<div class="timeline-body">';
$out.=$histo[$key]['message'];
$out.='</div>';
}
// Timeline footer
$footer = '';
// Contact for this action
if (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) {
$contactList = '';
foreach ($histo[$key]['socpeopleassigned'] as $cid => $Tab) {
$contact = new Contact($db);
$result = $contact->fetch($cid);
if ($result < 0)
dol_print_error($db, $contact->error);
if ($result > 0) {
$contactList.= !empty($contactList)?', ':'';
$contactList .= $contact->getNomUrl(1);
if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
if (! empty($contact->phone_pro))
$contactList .= '(' . dol_print_phone($contact->phone_pro) . ')';
}
}
}
$footer .= $langs->trans('ActionOnContact').' : '.$contactList;
}
elseif (empty($objcon->id) && isset($histo[$key]['contact_id']) && $histo[$key]['contact_id'] > 0)
{
$contact = new Contact($db);
$result = $contact->fetch($histo[$key]['contact_id']);
if ($result < 0)
dol_print_error($db, $contact->error);
if ($result > 0) {
$footer .= $contact->getNomUrl(1);
if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
if (! empty($contact->phone_pro))
$footer .= '(' . dol_print_phone($contact->phone_pro) . ')';
}
}
}
if(!empty($footer)){
$out.='<div class="timeline-footer">'.$footer.'</div>';
}
$out.='</div>'."\n"; // end timeline-item
$out.='</li>';
$out.='<!-- END timeline item -->';
$i++;
}
$out.="</ul>\n";
}
if ($noprint) return $out;
else print $out;
}

View File

@ -205,7 +205,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout =
'link' => '/projet/index.php?mainmenu=project&amp;leftmenu=',
'title' => (empty($conf->global->PROJECT_USE_OPPORTUNITIES) || $conf->global->PROJECT_USE_OPPORTUNITIES == 2 )
? (($conf->global->PROJECT_USE_OPPORTUNITIES == 2)?"Leads":"Projects")
: "LeadsOrProjects",
: "Projects",
'level' => 0,
'enabled' => $showmode = isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal),
'target' => $atarget,

View File

@ -0,0 +1,377 @@
<?php
/* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \defgroup zapier Module Zapier
* \brief Zapier module descriptor.
*
* \file htdocs/core/modules/modZapier.class.php
* \ingroup zapier
* \brief Description and activation file for module Zapier
*/
include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
/**
* Description and activation class for module Zapier
*/
class modZapier extends DolibarrModules
{
/**
* Constructor. Define names, constants, directories, boxes, permissions
*
* @param DoliDB $db Database handler
*/
public function __construct($db)
{
global $langs,$conf;
$this->db = $db;
// Id for module (must be unique).
// Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id).
$this->numero = 792000; // TODO Go on page https://wiki.dolibarr.org/index.php/List_of_modules_id to reserve id number for your module
// Key text used to identify module (for permissions, menus, etc...)
$this->rights_class = 'zapier';
// Family can be 'base' (core modules),'crm','financial','hr','projects','products','ecm','technic' (transverse modules),'interface' (link with external tools),'other','...'
// It is used to group modules by family in module setup page
$this->family = "interface";
// Module position in the family on 2 digits ('01', '10', '20', ...)
$this->module_position = 100;
// Gives the possibility for the module, to provide his own family info and position of this family (Overwrite $this->family and $this->module_position. Avoid this)
//$this->familyinfo = array('myownfamily' => array('position' => '01', 'label' => $langs->trans("MyOwnFamily")));
// Module label (no space allowed), used if translation string 'ModuleZapierName' not found (Zapier is name of module).
$this->name = preg_replace('/^mod/i', '', get_class($this));
// Module description, used if translation string 'ModuleZapierDesc' not found (Zapier is name of module).
$this->description = "ZapierDescription";
// Used only if file README.md and README-LL.md not found.
$this->descriptionlong = "Zapier description (Long)";
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
$this->version = 'development';
//Url to the file with your last numberversion of this module
//$this->url_last_version = 'http://www.example.com/versionmodule.txt';
// Key used in llx_const table to save module status enabled/disabled (where ZAPIERFORDOLIBARR is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
// Name of image file used for this module.
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
$this->picto = 'zapier';
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
$this->module_parts = array(
// Set this to 1 if module has its own trigger directory (core/triggers)
'triggers' => 1,
// Set this to 1 if module has its own login method file (core/login)
'login' => 0,
// Set this to 1 if module has its own substitution function file (core/substitutions)
'substitutions' => 0,
// Set this to 1 if module has its own menus handler directory (core/menus)
'menus' => 0,
// Set this to 1 if module overwrite template dir (core/tpl)
'tpl' => 0,
// Set this to 1 if module has its own barcode directory (core/modules/barcode)
'barcode' => 0,
// Set this to 1 if module has its own models directory (core/modules/xxx)
'models' => 0,
// Set this to 1 if module has its own theme directory (theme)
'theme' => 0,
// Set this to relative path of css file if module has its own css file
'css' => array(
// '/zapier/css/zapier.css.php',
),
// Set this to relative path of js file if module must load a js on all pages
'js' => array(
// '/zapier/js/zapier.js.php',
),
// Set here all hooks context managed by module. To find available hook context, make a "grep -r '>initHooks(' *" on source code. You can also set hook context 'all'
'hooks' => array(
// 'data' => array(
// 'hookcontext1',
// 'hookcontext2',
// ),
// 'entity' => '0',
),
// Set this to 1 if feature of module are opened to external users
'moduleforexternal' => 0,
);
// Data directories to create when module is enabled.
// Example: this->dirs = array("/zapier/temp","/zapier/subdir");
$this->dirs = array("/zapier/temp");
// Config pages. Put here list of php page, stored into zapier/admin directory, to use to setup module.
$this->config_page_url = array(
// "setup.php@zapier"
);
// Dependencies
// A condition to hide module
$this->hidden = false;
// List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...)
$this->depends = array();
// List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...)
$this->requiredby = array();
// List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...)
$this->conflictwith = array();
$this->langfiles = array("zapier");
// Minimum version of PHP required by module
//$this->phpmin = array(5, 5);
// Minimum version of Dolibarr required by module
$this->need_dolibarr_version = array(10, 0);
// Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
$this->warnings_activation = array();
// Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...)
$this->warnings_activation_ext = array();
// $this->automatic_activation = array(
// 'FR'=>'ZapierWasAutomaticallyActivatedBecauseOfYourCountryChoice',
// );
// If true, can't be disabled
// $this->always_enabled = true;
// Constants
// List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive)
// Example: $this->const=array(
// 1 => array('ZAPIERFORDOLIBARR_MYNEWCONST1', 'chaine', 'myvalue', 'This is a constant to add', 1),
// 2 => array('ZAPIERFORDOLIBARR_MYNEWCONST2', 'chaine', 'myvalue', 'This is another constant to add', 0, 'current', 1)
// );
$this->const = array(
// 1 => array('ZAPIERFORDOLIBARR_MYCONSTANT', 'chaine', 'avalue', 'This is a constant to add', 1, 'allentities', 1)
);
// Some keys to add into the overwriting translation tables
/*$this->overwrite_translation = array(
'en_US:ParentCompany'=>'Parent company or reseller',
'fr_FR:ParentCompany'=>'Maison mère ou revendeur'
)*/
if (! isset($conf->zapier) || ! isset($conf->zapier->enabled)) {
$conf->zapier = new stdClass();
$conf->zapier->enabled=0;
}
// Array to add new pages in new tabs
$this->tabs = array();
// Example:
// $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@zapier:$user->rights->zapier->read:/zapier/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1
// $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@zapier:$user->rights->othermodule->read:/zapier/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key.
// $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname
//
// Where objecttype can be
// 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member)
// 'contact' to add a tab in contact view
// 'contract' to add a tab in contract view
// 'group' to add a tab in group view
// 'intervention' to add a tab in intervention view
// 'invoice' to add a tab in customer invoice view
// 'invoice_supplier' to add a tab in supplier invoice view
// 'member' to add a tab in fundation member view
// 'opensurveypoll' to add a tab in opensurvey poll view
// 'order' to add a tab in customer order view
// 'order_supplier' to add a tab in supplier order view
// 'payment' to add a tab in payment view
// 'payment_supplier' to add a tab in supplier payment view
// 'product' to add a tab in product view
// 'propal' to add a tab in propal view
// 'project' to add a tab in project view
// 'stock' to add a tab in stock view
// 'thirdparty' to add a tab in third party view
// 'user' to add a tab in user view
// Dictionaries
$this->dictionaries=array();
/* Example:
$this->dictionaries=array(
'langs'=>'mylangfile@zapier',
// List of tables we want to see into dictonnary editor
'tabname'=>array(MAIN_DB_PREFIX."table1",MAIN_DB_PREFIX."table2",MAIN_DB_PREFIX."table3"),
// Label of tables
'tablib'=>array("Table1","Table2","Table3"),
// Request to select fields
'tabsql'=>array('SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table1 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table2 as f','SELECT f.rowid as rowid, f.code, f.label, f.active FROM '.MAIN_DB_PREFIX.'table3 as f'),
// Sort order
'tabsqlsort'=>array("label ASC","label ASC","label ASC"),
// List of fields (result of select to show dictionary)
'tabfield'=>array("code,label","code,label","code,label"),
// List of fields (list of fields to edit a record)
'tabfieldvalue'=>array("code,label","code,label","code,label"),
// List of fields (list of fields for insert)
'tabfieldinsert'=>array("code,label","code,label","code,label"),
// Name of columns with primary key (try to always name it 'rowid')
'tabrowid'=>array("rowid","rowid","rowid"),
// Condition to show each dictionary
'tabcond'=>array($conf->zapier->enabled,$conf->zapier->enabled,$conf->zapier->enabled)
);
*/
// Boxes/Widgets
// Add here list of php file(s) stored in zapier/core/boxes that contains class to show a widget.
$this->boxes = array(
// 0 => array(
// 'file' => 'zapierwidget1.php@zapier',
// 'note' => 'Widget provided by Zapier',
// 'enabledbydefaulton' => 'Home',
// ),
//1=>array('file'=>'zapierwidget2.php@zapier','note'=>'Widget provided by Zapier'),
//2=>array('file'=>'zapierwidget3.php@zapier','note'=>'Widget provided by Zapier')
);
// Cronjobs (List of cron jobs entries to add when module is enabled)
// unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week
$this->cronjobs = array(
// 0 => array(
// 'label' => 'MyJob label',
// 'jobtype' => 'method',
// 'class' => '/zapier/class/myobject.class.php',
// 'objectname' => 'MyObject',
// 'method' => 'doScheduledJob',
// 'parameters' => '',
// 'comment' => 'Comment',
// 'frequency' => 2,
// 'unitfrequency' => 3600,
// 'status' => 0,
// 'test' => '$conf->zapier->enabled',
// 'priority' => 50,
// ),
);
// Example: $this->cronjobs=array(
// 0=>array('label'=>'My label', 'jobtype'=>'method', 'class'=>'/dir/class/file.class.php', 'objectname'=>'MyClass', 'method'=>'myMethod', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>2, 'unitfrequency'=>3600, 'status'=>0, 'test'=>'$conf->zapier->enabled', 'priority'=>50),
// 1=>array('label'=>'My label', 'jobtype'=>'command', 'command'=>'', 'parameters'=>'param1, param2', 'comment'=>'Comment', 'frequency'=>1, 'unitfrequency'=>3600*24, 'status'=>0, 'test'=>'$conf->zapier->enabled', 'priority'=>50)
// );
// Permissions
// Permission array used by this module
$this->rights = array();
$r=0;
// Permission id (must not be already used)
$this->rights[$r][0] = $this->numero + $r;
// Permission label
$this->rights[$r][1] = 'Read myobject of Zapier';
// Permission by default for new user (0/1)
$this->rights[$r][3] = 1;
// In php code, permission will be checked by test if ($user->rights->zapier->level1->level2)
$this->rights[$r][4] = 'read';
// In php code, permission will be checked by test if ($user->rights->zapier->level1->level2)
$this->rights[$r][5] = '';
$r++;
$this->rights[$r][0] = $this->numero + $r;
$this->rights[$r][1] = 'Create/Update myobject of Zapier';
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'write';
$this->rights[$r][5] = '';
$r++;
$this->rights[$r][0] = $this->numero + $r;
$this->rights[$r][1] = 'Delete myobject of Zapier';
$this->rights[$r][3] = 1;
$this->rights[$r][4] = 'delete';
$this->rights[$r][5] = '';
// Main menu entries
$this->menu = array(); // List of menus to add
$r=0;
// Add here entries to declare new menus
// $this->menu[$r++]=array(
// 'fk_menu' => '', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
// 'type' => 'top', // This is a Top menu entry
// 'titre' => 'Zapier',
// 'mainmenu' => 'zapier',
// 'leftmenu' => '',
// 'url' => '/zapier/zapierindex.php',
// 'langs' => 'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
// 'position' => 1000+$r,
// 'enabled' => '$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled.
// 'perms' => '1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
// 'target' => '',
// 'user' => 2, // 0=Menu for internal users, 1=external users, 2=both
// );
/*
$this->menu[$r++]=array(
'fk_menu'=>'fk_mainmenu=zapier', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'type'=>'left', // This is a Left menu entry
'titre'=>'List MyObject',
'mainmenu'=>'zapier',
'leftmenu'=>'zapier_myobject_list',
'url'=>'/zapier/myobject_list.php',
'langs'=>'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>1000+$r,
'enabled'=>'$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
'perms'=>'1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
);
$this->menu[$r++]=array(
'fk_menu'=>'fk_mainmenu=zapier,fk_leftmenu=zapier', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode
'type'=>'left', // This is a Left menu entry
'titre'=>'New MyObject',
'mainmenu'=>'zapier',
'leftmenu'=>'zapier_myobject_new',
'url'=>'/zapier/myobject_page.php?action=create',
'langs'=>'zapier@zapier', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
'position'=>1000+$r,
'enabled'=>'$conf->zapier->enabled', // Define condition to show or hide menu entry. Use '$conf->zapier->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected.
'perms'=>'1', // Use 'perms'=>'$user->rights->zapier->level1->level2' if you want your menu with a permission rules
'target'=>'',
'user'=>2, // 0=Menu for internal users, 1=external users, 2=both
);
*/
// Exports
$r=1;
/* EXPORT */
/*
$langs->load("zapier@zapier");
$this->export_code[$r]=$this->rights_class.'_'.$r;
$this->export_label[$r]='MyObjectLines'; // Translation key (used only if key ExportDataset_xxx_z not found)
$this->export_icon[$r]='myobject@zapier';
$keyforclass = 'MyObject'; $keyforclassfile='/mymobule/class/myobject.class.php'; $keyforelement='myobject';
include DOL_DOCUMENT_ROOT.'/core/commonfieldsinexport.inc.php';
$keyforselect='myobject'; $keyforaliasextra='extra'; $keyforelement='myobject';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
//$this->export_dependencies_array[$r]=array('mysubobject'=>'ts.rowid', 't.myfield'=>array('t.myfield2','t.myfield3')); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields)
$this->export_sql_start[$r]='SELECT DISTINCT ';
$this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'myobject as t';
$this->export_sql_end[$r] .=' WHERE 1 = 1';
$this->export_sql_end[$r] .=' AND t.entity IN ('.getEntity('myobject').')';
$r++; */
}
/**
* Function called when module is enabled.
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
* It also creates data directories
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function init($options = '')
{
$result = $this->_load_tables('/zapier/sql/');
if ($result < 0) return -1; // Do not activate module if not allowed errors found on module SQL queries (the _load_table run sql with run_sql with error allowed parameter to 'default')
// Create extrafields
//include_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
//$extrafields = new ExtraFields($this->db);
//$result1=$extrafields->addExtraField('myattr1', "New Attr 1 label", 'boolean', 1, 3, 'thirdparty', 0, 0, '', '', 1, '', 0, 0, '', '', 'zapier@zapier', '$conf->zapier->enabled');
//$result2=$extrafields->addExtraField('myattr2', "New Attr 2 label", 'varchar', 1, 10, 'project', 0, 0, '', '', 1, '', 0, 0, '', '', 'zapier@zapier', '$conf->zapier->enabled');
//$result3=$extrafields->addExtraField('myattr3', "New Attr 3 label", 'varchar', 1, 10, 'bank_account', 0, 0, '', '', 1, '', 0, 0, '', '', 'zapier@zapier', '$conf->zapier->enabled');
//$result4=$extrafields->addExtraField('myattr4', "New Attr 4 label", 'select', 1, 3, 'thirdparty', 0, 1, '', array('options'=>array('code1'=>'Val1','code2'=>'Val2','code3'=>'Val3')), 1,'', 0, 0, '', '', 'zapier@zapier', '$conf->zapier->enabled');
//$result5=$extrafields->addExtraField('myattr5', "New Attr 5 label", 'text', 1, 10, 'user', 0, 0, '', '', 1, '', 0, 0, '', '', 'zapier@zapier', '$conf->zapier->enabled');
$sql = array();
return $this->_init($sql, $options);
}
/**
* Function called when module is disabled.
* Remove from database constants, boxes and permissions from Dolibarr database.
* Data directories are not deleted
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function remove($options = '')
{
$sql = array();
return $this->_remove($sql, $options);
}
}

View File

@ -43,7 +43,7 @@ llxHeader("", $langs->trans("Tools"), "");
$text=$langs->trans("Tools");
print load_fiche_titre($text);
print load_fiche_titre($text, '', 'generic');
// Show description of content
print '<div class="justify">'.$langs->trans("ToolsDesc").'</div><br><br>';

View File

@ -41,7 +41,8 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
if (empty($reshook)) {
print $object->showOptionals($extrafields, 'edit');
$params = isset($tpl_context) ? array('context' => $tpl_context) : array(); // BUG #11554 : Add context in params
print $object->showOptionals($extrafields, 'edit', $params); // BUG #11554 : Add context in params
}
?>

View File

@ -41,7 +41,7 @@ if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_
{
// for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid')
$morecss='';
if ($typeofextrafield == 'sellist') $morecss='maxwidth200';
if (in_array($typeofextrafield, array('link', 'sellist'))) $morecss='maxwidth200';
echo $extrafields->showInputField($key, $search_array_options[$search_options_pattern.$tmpkey], '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1);
}
print '</td>';

View File

@ -0,0 +1,530 @@
<?php
/* Copyright (C) 2017-2019 Frédéric France <frederic.france@netlogic.fr>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* \file core/triggers/interface_99_modZapier_ZapierTriggers.class.php
* \ingroup zapier
* \brief Example trigger.
*
*
* \remarks You can create other triggers by copying this one.
* - File name should be either:
* - interface_99_modZapier_MyTrigger.class.php
* - interface_99_all_MyTrigger.class.php
* - The file must stay in core/triggers
* - The class name must be InterfaceMytrigger
* - The constructor method must be named InterfaceMytrigger
* - The name property name must be MyTrigger
*/
require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
/**
* Class of triggers for Zapier module
*/
class InterfaceZapierTriggers extends DolibarrTriggers
{
/**
* @var DoliDB Database handler
*/
protected $db;
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct($db)
{
$this->db = $db;
$this->name = preg_replace('/^Interface/i', '', get_class($this));
$this->family = "technic";
$this->description = "Zapier triggers.";
// 'development', 'experimental', 'dolibarr' or version
$this->version = 'development';
$this->picto = 'zapier@zapier';
}
/**
* Trigger name
*
* @return string Name of trigger file
*/
public function getName()
{
return $this->name;
}
/**
* Trigger description
*
* @return string Description of trigger file
*/
public function getDesc()
{
return $this->description;
}
/**
* Function called when a Dolibarrr business event is done.
* All functions "runTrigger" are triggered if file
* is inside directory core/triggers
*
* @param string $action Event action code
* @param CommonObject $object Object
* @param User $user Object user
* @param Translate $langs Object langs
* @param Conf $conf Object conf
* @return int <0 if KO, 0 if no triggered ran, >0 if OK
*/
public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
{
global $db;
if (empty($conf->zapier->enabled)) {
// Module not active, we do nothing
return 0;
}
$logtriggeraction = false;
if ($action!='') {
$actions = explode('_', $action);
$sql = 'SELECT rowid, url FROM '.MAIN_DB_PREFIX.'zapier_hook';
$sql .= ' WHERE module="'.$db->escape(strtolower($actions[0])).'" AND action="'.$db->escape(strtolower($actions[1])).'"';
//setEventMessages($sql, null);
}
switch ($action) {
// Users
//case 'USER_CREATE':
//case 'USER_MODIFY':
//case 'USER_NEW_PASSWORD':
//case 'USER_ENABLEDISABLE':
//case 'USER_DELETE':
//case 'USER_SETINGROUP':
//case 'USER_REMOVEFROMGROUP':
// case 'USER_LOGIN':
// case 'USER_LOGIN_FAILED':
// case 'USER_LOGOUT':
// Warning: To increase performances, this action is triggered only if constant MAIN_ACTIVATE_UPDATESESSIONTRIGGER is set to 1.
// // case 'USER_UPDATE_SESSION':
// Actions
case 'ACTION_MODIFY':
//$logtriggeraction = true;
break;
case 'ACTION_CREATE':
$resql = $db->query($sql);
// TODO voir comment regrouper les webhooks en un post
while ($resql && $obj = $db->fetch_array($resql)) {
$cleaned = cleanObjectDatas(dol_clone($object));
$cleaned = cleanAgendaEventsDatas($cleaned);
$json = json_encode($cleaned);
// call the zapierPostWebhook() function
zapierPostWebhook($obj['url'], $json);
//setEventMessages($obj['url'], null);
}
$logtriggeraction = true;
break;
case 'ACTION_DELETE':
//$logtriggeraction = true;
break;
// Groups
//case 'GROUP_CREATE':
//case 'GROUP_MODIFY':
//case 'GROUP_DELETE':
// Companies
case 'COMPANY_CREATE':
$resql = $db->query($sql);
while ($resql && $obj = $db->fetch_array($resql)) {
$cleaned = cleanObjectDatas(dol_clone($object));
$json = json_encode($cleaned);
// call the zapierPostWebhook() function
zapierPostWebhook($obj['url'], $json);
}
$logtriggeraction = true;
break;
case 'COMPANY_MODIFY':
$resql = $db->query($sql);
while ($resql && $obj = $db->fetch_array($resql)) {
$cleaned = cleanObjectDatas(dol_clone($object));
$json = json_encode($cleaned);
// call the zapierPostWebhook() function
zapierPostWebhook($obj['url'], $json);
}
$logtriggeraction = true;
break;
case 'COMPANY_DELETE':
//$logtriggeraction = true;
break;
// Contacts
case 'CONTACT_CREATE':
case 'CONTACT_MODIFY':
case 'CONTACT_DELETE':
case 'CONTACT_ENABLEDISABLE':
// Products
// case 'PRODUCT_CREATE':
// case 'PRODUCT_MODIFY':
// case 'PRODUCT_DELETE':
// case 'PRODUCT_PRICE_MODIFY':
// case 'PRODUCT_SET_MULTILANGS':
// case 'PRODUCT_DEL_MULTILANGS':
//Stock mouvement
// case 'STOCK_MOVEMENT':
//MYECMDIR
// case 'MYECMDIR_DELETE':
// case 'MYECMDIR_CREATE':
// case 'MYECMDIR_MODIFY':
// Customer orders
case 'ORDER_CREATE':
$resql = $db->query($sql);
while ($resql && $obj = $db->fetch_array($resql)) {
$cleaned = cleanObjectDatas(dol_clone($object));
$json = json_encode($cleaned);
// call the zapierPostWebhook() function
zapierPostWebhook($obj['url'], $json);
}
$logtriggeraction = true;
break;
case 'ORDER_CLONE':
break;
case 'ORDER_VALIDATE':
break;
case 'ORDER_DELETE':
case 'ORDER_CANCEL':
case 'ORDER_SENTBYMAIL':
case 'ORDER_CLASSIFY_BILLED':
case 'ORDER_SETDRAFT':
case 'LINEORDER_INSERT':
case 'LINEORDER_UPDATE':
case 'LINEORDER_DELETE':
// Supplier orders
// case 'ORDER_SUPPLIER_CREATE':
// case 'ORDER_SUPPLIER_CLONE':
// case 'ORDER_SUPPLIER_VALIDATE':
// case 'ORDER_SUPPLIER_DELETE':
// case 'ORDER_SUPPLIER_APPROVE':
// case 'ORDER_SUPPLIER_REFUSE':
// case 'ORDER_SUPPLIER_CANCEL':
// case 'ORDER_SUPPLIER_SENTBYMAIL':
// case 'ORDER_SUPPLIER_DISPATCH':
// case 'LINEORDER_SUPPLIER_DISPATCH':
// case 'LINEORDER_SUPPLIER_CREATE':
// case 'LINEORDER_SUPPLIER_UPDATE':
// Proposals
// case 'PROPAL_CREATE':
// case 'PROPAL_CLONE':
// case 'PROPAL_MODIFY':
// case 'PROPAL_VALIDATE':
// case 'PROPAL_SENTBYMAIL':
// case 'PROPAL_CLOSE_SIGNED':
// case 'PROPAL_CLOSE_REFUSED':
// case 'PROPAL_DELETE':
// case 'LINEPROPAL_INSERT':
// case 'LINEPROPAL_UPDATE':
// case 'LINEPROPAL_DELETE':
// SupplierProposal
// case 'SUPPLIER_PROPOSAL_CREATE':
// case 'SUPPLIER_PROPOSAL_CLONE':
// case 'SUPPLIER_PROPOSAL_MODIFY':
// case 'SUPPLIER_PROPOSAL_VALIDATE':
// case 'SUPPLIER_PROPOSAL_SENTBYMAIL':
// case 'SUPPLIER_PROPOSAL_CLOSE_SIGNED':
// case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
// case 'SUPPLIER_PROPOSAL_DELETE':
// case 'LINESUPPLIER_PROPOSAL_INSERT':
// case 'LINESUPPLIER_PROPOSAL_UPDATE':
// case 'LINESUPPLIER_PROPOSAL_DELETE':
// Contracts
// case 'CONTRACT_CREATE':
// case 'CONTRACT_ACTIVATE':
// case 'CONTRACT_CANCEL':
// case 'CONTRACT_CLOSE':
// case 'CONTRACT_DELETE':
// case 'LINECONTRACT_INSERT':
// case 'LINECONTRACT_UPDATE':
// case 'LINECONTRACT_DELETE':
// Bills
// case 'BILL_CREATE':
// case 'BILL_CLONE':
// case 'BILL_MODIFY':
// case 'BILL_VALIDATE':
// case 'BILL_UNVALIDATE':
// case 'BILL_SENTBYMAIL':
// case 'BILL_CANCEL':
// case 'BILL_DELETE':
// case 'BILL_PAYED':
// case 'LINEBILL_INSERT':
// case 'LINEBILL_UPDATE':
// case 'LINEBILL_DELETE':
//Supplier Bill
// case 'BILL_SUPPLIER_CREATE':
// case 'BILL_SUPPLIER_UPDATE':
// case 'BILL_SUPPLIER_DELETE':
// case 'BILL_SUPPLIER_PAYED':
// case 'BILL_SUPPLIER_UNPAYED':
// case 'BILL_SUPPLIER_VALIDATE':
// case 'BILL_SUPPLIER_UNVALIDATE':
// case 'LINEBILL_SUPPLIER_CREATE':
// case 'LINEBILL_SUPPLIER_UPDATE':
// case 'LINEBILL_SUPPLIER_DELETE':
// Payments
// case 'PAYMENT_CUSTOMER_CREATE':
// case 'PAYMENT_SUPPLIER_CREATE':
// case 'PAYMENT_ADD_TO_BANK':
// case 'PAYMENT_DELETE':
// Online
// case 'PAYMENT_PAYBOX_OK':
// case 'PAYMENT_PAYPAL_OK':
// case 'PAYMENT_STRIPE_OK':
// Donation
// case 'DON_CREATE':
// case 'DON_UPDATE':
// case 'DON_DELETE':
// Interventions
// case 'FICHINTER_CREATE':
// case 'FICHINTER_MODIFY':
// case 'FICHINTER_VALIDATE':
// case 'FICHINTER_DELETE':
// case 'LINEFICHINTER_CREATE':
// case 'LINEFICHINTER_UPDATE':
// case 'LINEFICHINTER_DELETE':
// Members
// case 'MEMBER_CREATE':
// case 'MEMBER_VALIDATE':
// case 'MEMBER_SUBSCRIPTION':
// case 'MEMBER_MODIFY':
// case 'MEMBER_NEW_PASSWORD':
// case 'MEMBER_RESILIATE':
// case 'MEMBER_DELETE':
// Categories
// case 'CATEGORY_CREATE':
// case 'CATEGORY_MODIFY':
// case 'CATEGORY_DELETE':
// case 'CATEGORY_SET_MULTILANGS':
// Projects
// case 'PROJECT_CREATE':
// case 'PROJECT_MODIFY':
// case 'PROJECT_DELETE':
// Project tasks
// case 'TASK_CREATE':
// case 'TASK_MODIFY':
// case 'TASK_DELETE':
// Task time spent
// case 'TASK_TIMESPENT_CREATE':
// case 'TASK_TIMESPENT_MODIFY':
// case 'TASK_TIMESPENT_DELETE':
// Shipping
// case 'SHIPPING_CREATE':
// case 'SHIPPING_MODIFY':
// case 'SHIPPING_VALIDATE':
// case 'SHIPPING_SENTBYMAIL':
// case 'SHIPPING_BILLED':
// case 'SHIPPING_CLOSED':
// case 'SHIPPING_REOPEN':
// case 'SHIPPING_DELETE':
}
if ($logtriggeraction) {
dol_syslog("Trigger '" . $this->name . "' for action '.$action.' launched by " . __FILE__ . " id=" . $object->id);
}
return 0;
}
}
/**
* Post webhook in zapier with object data
*
* @param string $url url provided by zapier
* @param string $json data to send
* @return void
*/
function zapierPostWebhook($url, $json)
{
$headers = array('Accept: application/json', 'Content-Type: application/json');
// TODO supprimer le webhook en cas de mauvaise réponse
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
curl_close($ch);
}
/**
* Clean sensible object datas
*
* @param object $toclean Object to clean
* @return array Array of cleaned object properties
*/
function cleanObjectDatas($toclean)
{
// Remove $db object property for object
unset($toclean->db);
// Remove linkedObjects. We should already have linkedObjectIds that avoid huge responses
unset($toclean->linkedObjects);
unset($toclean->lines); // should be ->lines
unset($toclean->fields);
unset($toclean->oldline);
unset($toclean->error);
unset($toclean->errors);
unset($toclean->ref_previous);
unset($toclean->ref_next);
unset($toclean->ref_int);
unset($toclean->projet); // Should be fk_project
unset($toclean->project); // Should be fk_project
unset($toclean->author); // Should be fk_user_author
unset($toclean->timespent_old_duration);
unset($toclean->timespent_id);
unset($toclean->timespent_duration);
unset($toclean->timespent_date);
unset($toclean->timespent_datehour);
unset($toclean->timespent_withhour);
unset($toclean->timespent_fk_user);
unset($toclean->timespent_note);
unset($toclean->statuts);
unset($toclean->statuts_short);
unset($toclean->statuts_logo);
unset($toclean->statuts_long);
unset($toclean->element);
unset($toclean->fk_element);
unset($toclean->table_element);
unset($toclean->table_element_line);
unset($toclean->picto);
unset($toclean->skip_update_total);
unset($toclean->context);
// Remove the $oldcopy property because it is not supported by the JSON
// encoder. The following error is generated when trying to serialize
// it: "Error encoding/decoding JSON: Type is not supported"
// Note: Event if this property was correctly handled by the JSON
// encoder, it should be ignored because keeping it would let the API
// have a very strange behavior: calling PUT and then GET on the same
// resource would give different results:
// PUT /objects/{id} -> returns object with oldcopy = previous version of the object
// GET /objects/{id} -> returns object with oldcopy empty
unset($toclean->oldcopy);
// If object has lines, remove $db property
if (isset($toclean->lines) && count($toclean->lines) > 0) {
$nboflines = count($toclean->lines);
for ($i=0; $i < $nboflines; $i++) {
$this->cleanObjectDatas($toclean->lines[$i]);
}
}
// If object has linked objects, remove $db property
/*
if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) {
foreach($toclean->linkedObjects as $type_object => $linked_object) {
foreach($linked_object as $toclean2clean) {
$this->cleanObjectDatas($toclean2clean);
}
}
}*/
return $toclean;
}
/**
* Clean sensible object datas
*
* @param object $toclean Object to clean
* @return array Array of cleaned object properties
*/
function cleanAgendaEventsDatas($toclean)
{
unset($toclean->usermod);
unset($toclean->libelle);
//unset($toclean->array_options);
unset($toclean->context);
unset($toclean->canvas);
unset($toclean->contact);
unset($toclean->contact_id);
unset($toclean->thirdparty);
unset($toclean->user);
unset($toclean->origin);
unset($toclean->origin_id);
unset($toclean->ref_ext);
unset($toclean->statut);
unset($toclean->country);
unset($toclean->country_id);
unset($toclean->country_code);
unset($toclean->barcode_type);
unset($toclean->barcode_type_code);
unset($toclean->barcode_type_label);
unset($toclean->barcode_type_coder);
unset($toclean->mode_reglement_id);
unset($toclean->cond_reglement_id);
unset($toclean->cond_reglement);
unset($toclean->fk_delivery_address);
unset($toclean->shipping_method_id);
unset($toclean->fk_account);
unset($toclean->total_ht);
unset($toclean->total_tva);
unset($toclean->total_localtax1);
unset($toclean->total_localtax2);
unset($toclean->total_ttc);
unset($toclean->fk_incoterms);
unset($toclean->libelle_incoterms);
unset($toclean->location_incoterms);
unset($toclean->name);
unset($toclean->lastname);
unset($toclean->firstname);
unset($toclean->civility_id);
unset($toclean->contact);
unset($toclean->societe);
return $toclean;
}

View File

@ -154,7 +154,7 @@ if ($resql)
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="type" value="'.$type.'">';
print_barre_liste($langs->trans("Donations"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton);
print_barre_liste($langs->trans("Donations"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, $newcardbutton);
if ($search_all)
{

View File

@ -473,7 +473,7 @@ if ($resql)
$newcardbutton.= dolGetButtonTitle($langs->trans('NewTrip'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/expensereport/card.php?action=create');
}
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
}
$topicmail="SendExpenseReport";

View File

@ -248,7 +248,7 @@ $today = dol_mktime(
* Create mode
*/
if ($action == 'create') {
print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'title_commercial.png');
print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'commercial');
$object = new Fichinter($db); // Source invoice
//$object = new Managementfichinter($db); // Source invoice
@ -439,7 +439,7 @@ $date_next_execution = (GETPOST('remonth') ? dol_mktime(
else
dol_print_error('', "Error, no invoice ".$object->id);
} elseif ($action == 'selsocforcreatefrommodel') {
print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'title_commercial.png');
print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'commercial');
dol_fiche_head('');
print '<form name="fichinter" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
@ -810,7 +810,7 @@ $date_next_execution = (GETPOST('remonth') ? dol_mktime(
'',
$num,
'',
'title_commercial.png'
'commercial'
);
print $langs->trans("ToCreateAPredefinedInterventional").'<br><br>';

View File

@ -327,7 +327,7 @@ if ($resql)
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'commercial', 0, $newcardbutton, '', $limit);
$topicmail="Information";
$modelmail="intervention";

View File

@ -65,7 +65,7 @@ $dir=$conf->ficheinter->dir_temp;
llxHeader('', $title);
print load_fiche_titre($title, '', 'title_commercial.png');
print load_fiche_titre($title, '', 'commercial');
dol_mkdir($dir);

View File

@ -649,7 +649,7 @@ if ($resql)
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="viewstatut" value="'.$viewstatut.'">';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'commercial', 0, $newcardbutton, '', $limit);
$topicmail="SendOrderRef";
$modelmail="order_supplier_send";

View File

@ -77,7 +77,7 @@ $childids[]=$user->id;
llxHeader('', $langs->trans('HRMArea'));
print load_fiche_titre($langs->trans("HRMArea"), '', 'title_hrm.png');
print load_fiche_titre($langs->trans("HRMArea"), '', 'hrm');
if (! empty($setupcompanynotcomplete))

View File

@ -80,7 +80,7 @@ llxHeader('', $title);
$resultboxes=FormOther::getBoxesArea($user, "0"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb)
print load_fiche_titre($langs->trans("HomeArea"), $resultboxes['selectboxlist'], 'title_home');
print load_fiche_titre($langs->trans("HomeArea"), $resultboxes['selectboxlist'], 'home');
if (! empty($conf->global->MAIN_MOTD))
{

View File

@ -0,0 +1,22 @@
-- Copyright (C) ---Put here your own copyright and developer email---
--
-- This program 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.
--
-- This program 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 this program. If not, see http://www.gnu.org/licenses/.
--ALTER TABLE llx_zapier_hook ADD INDEX idx_fieldobject (fieldobject);
--ALTER TABLE llx_zapier_hook ADD UNIQUE INDEX uk_zapier_hook_fieldxy(fieldx, fieldy);
--ALTER TABLE llx_zapier_hook ADD CONSTRAINT llx_zapier_hook_fk_field FOREIGN KEY (fk_field) REFERENCES llx_zapier_myotherobject(rowid);

View File

@ -0,0 +1,29 @@
-- Copyright (C) ---Put here your own copyright and developer email---
--
-- This program 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.
--
-- This program 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 this program. If not, see http://www.gnu.org/licenses/.
CREATE TABLE llx_zapier_hook(
rowid integer AUTO_INCREMENT PRIMARY KEY,
entity integer DEFAULT 1 NOT NULL,
url varchar(255),
event varchar(255),
module varchar(128),
action varchar(128),
status integer,
date_creation DATETIME NOT NULL,
fk_user integer NOT NULL,
tms TIMESTAMP NOT NULL,
import_key varchar(14)
) ENGINE=innodb;

View File

@ -0,0 +1,23 @@
-- Copyright (C) ---Put here your own copyright and developer email---
--
-- This program 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.
--
-- This program 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 this program. If not, see http://www.gnu.org/licenses/.
create table llx_zapier_hook_extrafields
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
tms timestamp,
fk_object integer NOT NULL,
import_key varchar(14) -- import key
) ENGINE=innodb;

View File

@ -75,3 +75,5 @@ DirectPayment=Direct payment
DirectPaymentButton=Direct cash payment button
InvoiceIsAlreadyValidated=Invoice is already validated
NoLinesToBill=No lines to bill
CustomReceipt=Custom Receipt
ReceiptName=Receipt Name

View File

@ -4,6 +4,7 @@ LatestBOMModified=Latest %s Bills of materials modified
BillOfMaterials=Bill of Material
BOMsSetup=Setup of module BOM
ListOfBOMs=List of bills of material - BOM
ListOfManufacturingOrders=List of Manufacturing Orders
NewBOM=New bill of material
ProductBOMHelp=Product to create with this BOM
BOMsNumberingModules=BOM numbering templates
@ -16,4 +17,8 @@ ValueOfMeansLoss=Value of 0.95 means an average of 5%% of loss during the produc
DeleteBillOfMaterials=Delete Bill Of Materials
ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Material?
MenuMRP=Manufacturing Orders
NewMO=New Manufacturing Order
NewMO=New Manufacturing Order
QtyToProduce=Qty to produce
DateStartPlannedMo=Date start planned
DateEndPlannedMo=Date end planned
KeepEmptyForAsap=Empty means 'As Soon As Possible'

View File

@ -86,8 +86,8 @@ WhichIamLinkedToProject=which I'm linked to project
Time=Time
ListOfTasks=List of tasks
GoToListOfTimeConsumed=Go to list of time consumed
GoToListOfTasks=Go to list of tasks
GoToGanttView=Go to Gantt view
GoToListOfTasks=Show as list
GoToGanttView=show as Gantt
GanttView=Gantt View
ListProposalsAssociatedProject=List of the commercial proposals related to the project
ListOrdersAssociatedProject=List of sales orders related to the project

View File

@ -137,6 +137,10 @@ NoUnreadTicketsFound=No unread ticket found
TicketViewAllTickets=View all tickets
TicketViewNonClosedOnly=View only open tickets
TicketStatByStatus=Tickets by status
OrderByDateAsc=Sort by ascending date
OrderByDateDesc=Sort by descending date
MessagingViewType=Show as messaging list
MessageListViewType=Show as table list
#
# Ticket card

View File

@ -0,0 +1,53 @@
# Copyright (C) 2019 Frédéric FRANCE <frederic.france@free.fr>
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#
# Generic
#
# Module label 'ModuleZapierForDolibarrName'
ModuleZapierForDolibarrName = ZapierForDolibarr
# Module description 'ModuleZapierForDolibarrDesc'
ModuleZapierForDolibarrDesc = ZapierForDolibarr description
#
# Admin page
#
ZapierForDolibarrSetup = ZapierForDolibarr setup
Settings = Settings
ZapierForDolibarrSetupPage = ZapierForDolibarr setup page
ZAPIERFORDOLIBARR_MYPARAM1 = My param 1
ZAPIERFORDOLIBARR_MYPARAM1Tooltip = My param 1 tooltip
ZAPIERFORDOLIBARR_MYPARAM2=My param 2
ZAPIERFORDOLIBARR_MYPARAM2Tooltip=My param 2 tooltip
#
# About page
#
About = About
ZapierForDolibarrAbout = About ZapierForDolibarr
ZapierForDolibarrAboutPage = ZapierForDolibarr about page
#
# Sample page
#
MyPageName = My page name
#
# Sample widget
#
MyWidget = My widget
MyWidgetDescription = My widget description

View File

@ -0,0 +1,48 @@
# Copyright (C) 2019 Frédéric FRANCE <frederic.france@free.fr>
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
#
# Générique
#
# Module label 'ModuleZapierForDolibarrName'
ModuleZapierForDolibarrName = ZapierForDolibarr
# Module description 'ModuleZapierForDolibarrDesc'
ModuleZapierForDolibarrDesc = Description de ZapierForDolibarr
#
# Page d'administration
#
ZapierForDolibarrSetup = Configuration du module ZapierForDolibarr
Settings = Réglages
ZapierForDolibarrSetupPage = Page de configuration du module ZapierForDolibarr
#
# Page À propos
#
About = À propos
ZapierForDolibarrAbout = À propos de ZapierForDolibarr
ZapierForDolibarrAboutPage = Page à propos de ZapierForDolibarr
#
# Page d'exemple
#
MyPageName = Nom de ma page
#
# Box d'exemple
#
MyWidget = Mon widget
MyWidgetDescription = Description de mon widget

View File

@ -1463,7 +1463,7 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr
if ($conf->browser->layout == 'phone') $enablebrowsernotif=false;
if ($enablebrowsernotif)
{
print '<!-- Includes JS of Dolibarr (brwoser layout = '.$conf->browser->layout.')-->'."\n";
print '<!-- Includes JS of Dolibarr (browser layout = '.$conf->browser->layout.')-->'."\n";
print '<script src="'.DOL_URL_ROOT.'/core/js/lib_notification.js.php'.($ext?'?'.$ext:'').'"></script>'."\n";
}
}

View File

@ -190,7 +190,7 @@ if ($action == 'create')
dol_fiche_head(array(), '');
print '<table class="border centpercent">'."\n";
print '<table class="border centpercent tableforfieldcreate">'."\n";
// Common attributes
include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php';

View File

@ -245,7 +245,7 @@ print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
$newcardbutton='';
$newcardbutton.= dolGetButtonTitle($langs->trans('NewSurvey'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/opensurvey/wizard/index.php', '', $user->rights->opensurvey->write);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $newcardbutton, '', $limit);
// Add code for pre mass action (confirmation or email presend form)
$topicmail="SendOpenSurveyRef";

View File

@ -77,7 +77,7 @@ if ((isset($_GET["type"]) && $_GET["type"] == 1) || empty($conf->product->enable
llxHeader("", $langs->trans("ProductsAndServices"), $helpurl);
$linkback="";
print load_fiche_titre($transAreaType, $linkback, 'title_products.png');
print load_fiche_titre($transAreaType, $linkback, 'products');
print '<div class="fichecenter"><div class="fichethirdleft">';

View File

@ -87,81 +87,17 @@ $usercanread = (($user->rights->stock->lire));
$usercancreate = (($user->rights->stock->creer));
$usercandelete = (($user->rights->stock->supprimer));
// Ajout entrepot
if ($action == 'add' && $user->rights->stock->creer)
$parameters=array('id'=>$id, 'ref'=>$ref);
$reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
if (empty($reshook))
{
$object->ref = GETPOST("ref");
$object->fk_parent = GETPOST("fk_parent");
$object->libelle = GETPOST("libelle");
$object->description = GETPOST("desc");
$object->statut = GETPOST("statut");
$object->lieu = GETPOST("lieu");
$object->address = GETPOST("address");
$object->zip = GETPOST("zipcode");
$object->town = GETPOST("town");
$object->country_id = GETPOST("country_id");
if (! empty($object->libelle))
// Ajout entrepot
if ($action == 'add' && $user->rights->stock->creer)
{
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
if ($ret < 0) {
$error++;
$action = 'create';
}
if (! $error) {
$id = $object->create($user);
if ($id > 0) {
setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
if (!empty($backtopage)) {
header("Location: " . $backtopage);
exit;
} else {
header("Location: card.php?id=" . $id);
exit;
}
} else {
$action = 'create';
setEventMessages($object->error, $object->errors, 'errors');
}
}
}
else
{
setEventMessages($langs->trans("ErrorWarehouseRefRequired"), null, 'errors');
$action="create"; // Force retour sur page creation
}
}
// Delete warehouse
if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->stock->supprimer)
{
$object->fetch(GETPOST('id', 'int'));
$result=$object->delete($user);
if ($result > 0)
{
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
header("Location: ".DOL_URL_ROOT.'/product/stock/list.php?restore_lastsearch_values=1');
exit;
}
else
{
setEventMessages($object->error, $object->errors, 'errors');
$action='';
}
}
// Modification entrepot
if ($action == 'update' && $cancel <> $langs->trans("Cancel"))
{
if ($object->fetch($id))
{
$object->libelle = GETPOST("libelle");
$object->ref = GETPOST("ref");
$object->fk_parent = GETPOST("fk_parent");
$object->libelle = GETPOST("libelle");
$object->description = GETPOST("desc");
$object->statut = GETPOST("statut");
$object->lieu = GETPOST("lieu");
@ -170,57 +106,127 @@ if ($action == 'update' && $cancel <> $langs->trans("Cancel"))
$object->town = GETPOST("town");
$object->country_id = GETPOST("country_id");
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
if ($ret < 0) $error++;
if (! empty($object->libelle))
{
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
if ($ret < 0) {
$error++;
$action = 'create';
}
if (! $error) {
$ret = $object->update($id, $user);
if ($ret < 0) $error++;
}
if (! $error) {
$id = $object->create($user);
if ($id > 0) {
setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
if ($error) {
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
if (!empty($backtopage)) {
header("Location: " . $backtopage);
exit;
} else {
header("Location: card.php?id=" . $id);
exit;
}
} else {
$action = 'create';
setEventMessages($object->error, $object->errors, 'errors');
}
}
}
else
{
setEventMessages($langs->trans("ErrorWarehouseRefRequired"), null, 'errors');
$action="create"; // Force retour sur page creation
}
}
// Delete warehouse
if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->stock->supprimer)
{
$object->fetch(GETPOST('id', 'int'));
$result=$object->delete($user);
if ($result > 0)
{
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
header("Location: ".DOL_URL_ROOT.'/product/stock/list.php?restore_lastsearch_values=1');
exit;
}
else
{
setEventMessages($object->error, $object->errors, 'errors');
$action='';
}
}
// Modification entrepot
if ($action == 'update' && $cancel <> $langs->trans("Cancel"))
{
if ($object->fetch($id))
{
$object->libelle = GETPOST("libelle");
$object->fk_parent = GETPOST("fk_parent");
$object->description = GETPOST("desc");
$object->statut = GETPOST("statut");
$object->lieu = GETPOST("lieu");
$object->address = GETPOST("address");
$object->zip = GETPOST("zipcode");
$object->town = GETPOST("town");
$object->country_id = GETPOST("country_id");
// Fill array 'array_options' with data from add form
$ret = $extrafields->setOptionalsFromPost($extralabels, $object);
if ($ret < 0) $error++;
if (! $error) {
$ret = $object->update($id, $user);
if ($ret < 0) $error++;
}
if ($error) {
$action = 'edit';
setEventMessages($object->error, $object->errors, 'errors');
} else {
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
$action = '';
}
}
else
{
$action = 'edit';
setEventMessages($object->error, $object->errors, 'errors');
} else {
$categories = GETPOST('categories', 'array');
$object->setCategories($categories);
$action = '';
}
}
}
else
elseif ($action == 'update_extras') {
$object->oldcopy = dol_clone($object);
// Fill array 'array_options' with data from update form
$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute', 'none'));
if ($ret < 0) $error++;
if (! $error) {
$result = $object->insertExtraFields();
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
}
}
if ($error) $action = 'edit_extras';
}
if ($cancel == $langs->trans("Cancel"))
{
$action = 'edit';
setEventMessages($object->error, $object->errors, 'errors');
$action = '';
}
// Actions to build doc
$upload_dir = $conf->stock->dir_output;
$permissioncreate = $user->rights->stock->creer;
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
}
elseif ($action == 'update_extras') {
$object->oldcopy = dol_clone($object);
// Fill array 'array_options' with data from update form
$extralabels = $extrafields->fetch_name_optionals_label($object->table_element);
$ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute', 'none'));
if ($ret < 0) $error++;
if (! $error) {
$result = $object->insertExtraFields();
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
}
}
if ($error) $action = 'edit_extras';
}
if ($cancel == $langs->trans("Cancel"))
{
$action = '';
}
// Actions to build doc
$upload_dir = $conf->stock->dir_output;
$permissioncreate = $user->rights->stock->creer;
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
/*

View File

@ -184,7 +184,7 @@ if ($result)
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print_barre_liste($langs->trans("ListOfWarehouses"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'title_generic.png', 0, $newcardbutton, '', $limit);
print_barre_liste($langs->trans("ListOfWarehouses"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $totalnboflines, 'generic', 0, $newcardbutton, '', $limit);
if ($sall)
{

View File

@ -728,7 +728,7 @@ if ($resql)
if ($id > 0) print '<input type="hidden" name="id" value="'.$id.'">';
if ($id > 0) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit);
else print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic', 0, '', '', $limit);
else print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
if ($sall)
{

View File

@ -706,7 +706,7 @@ if ($resql)
if ($id > 0) print '<input type="hidden" name="id" value="'.$id.'">';
if ($id > 0) print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit);
else print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic', 0, '', '', $limit);
else print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
if ($sall)
{

View File

@ -438,7 +438,7 @@ $head[1][1] = $langs->trans("ReplenishmentOrders");
$head[1][2] = 'replenishorders';
print load_fiche_titre($langs->trans('Replenishment'), '', 'title_generic.png');
print load_fiche_titre($langs->trans('Replenishment'), '', 'generic');
dol_fiche_head($head, 'replenish', '', -1, '');

View File

@ -93,7 +93,7 @@ $texte = $langs->trans('ReplenishmentOrders');
llxHeader('', $texte, $helpurl, '');
print load_fiche_titre($langs->trans('Replenishment'), '', 'title_generic.png');
print load_fiche_titre($langs->trans('Replenishment'), '', 'generic');
$head = array();
$head[0][0] = DOL_URL_ROOT.'/product/stock/replenish.php';

View File

@ -53,7 +53,7 @@ if (empty($conf) || ! is_object($conf)) {
</script>';
print load_fiche_titre($langs->trans("StockCorrection"), '', 'title_generic.png');
print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic');
print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$id.'" method="post">'."\n";

View File

@ -53,7 +53,7 @@ if (empty($conf) || ! is_object($conf)) {
}
}
print load_fiche_titre($langs->trans("StockTransfer"), '', 'title_generic.png');
print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic');
print '<form action="'.$_SERVER["PHP_SELF"].'?id='.$id.'" method="post">'."\n";

View File

@ -201,6 +201,14 @@ if (($id > 0 && is_numeric($id)) || ! empty($ref))
print nl2br($object->description);
print '</td></tr>';
// Bill time
if (empty($conf->global->PROJECT_HIDE_TASKS) && ! empty($conf->global->PROJECT_BILL_TIME_SPENT))
{
print '<tr><td>'.$langs->trans("BillTime").'</td><td>';
print yn($object->usage_bill_time);
print '</td></tr>';
}
// Categories
if($conf->categorie->enabled) {
print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
@ -234,10 +242,10 @@ if ($user->rights->projet->all->creer || $user->rights->projet->creer) {
$linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam);
$linktolist = dolGetButtonTitle($langs->trans('GoToListOfTasks'), '', 'fa fa-tasks paddingleft', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id);
$linktolist = dolGetButtonTitle($langs->trans('GoToListOfTasks'), '', 'fa fa-list-alt paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition'));
//print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'title_generic.png', 0, '', '', 0, 1);
print load_fiche_titre($title, $linktolist.' &nbsp; '.$linktocreatetask, 'title_generic.png');
//print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
print load_fiche_titre($title, $linktolist.' &nbsp; '.$linktocreatetask, 'generic');
// Get list of tasks in tasksarray and taskarrayfiltered

View File

@ -88,7 +88,7 @@ $morehtml.='</SELECT>';
$morehtml.='<input type="submit" class="button" name="refresh" value="'.$langs->trans("Refresh").'">';
$morehtml.='</form>';
print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, -1, 'title_project.png', 0, $morehtml);
print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', '', '', '', 0, -1, 'project', 0, $morehtml);
// Show description of content
print '<div class="opacitymedium">';

View File

@ -669,10 +669,10 @@ elseif ($id > 0 || ! empty($ref))
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
$title=$langs->trans("ListOfTasks");
$linktotasks = dolGetButtonTitle($langs->trans('GoToGanttView'), '', 'fa fa-calendar-minus-o paddingleft', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1');
$linktotasks = dolGetButtonTitle($langs->trans('GoToGanttView'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition'));
//print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'title_generic.png', 0, '', '', 0, 1);
print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'title_generic.png');
//print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'generic');
// Get list of tasks in tasksarray and taskarrayfiltered
// We need all tasks (even not limited to a user because a task to user can have a parent that is not affected to him).

View File

@ -941,7 +941,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
$title=$langs->trans("ListTaskTimeUserProject");
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic', 0, $linktocreatetime, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $linktocreatetime, '', $limit);
}
else
{
@ -949,7 +949,7 @@ if (($id > 0 || ! empty($ref)) || $projectidforalltimes > 0)
$title=$langs->trans("ListTaskTimeForTask");
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic', 0, $linktocreatetime, '', $limit);
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'generic', 0, $linktocreatetime, '', $limit);
}
$i = 0;

View File

@ -645,6 +645,7 @@ print '<tr><td>'.$langs->trans("URLPhoto").'</td><td><input type="text" name="ph
// Public
print '<tr><td>'.$langs->trans("Public").'</td><td><input type="checkbox" name="public"></td></tr>'."\n";
// Other attributes
$tpl_context = 'public'; //BUG #11554 : define templae context to public
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
// Comments
print '<tr>';

Some files were not shown because too many files have changed in this diff Show More