Commit 9f248dfc authored by Julien Muchembled's avatar Julien Muchembled

Merge remote-tracking branch 'origin/master' into cmf_upgrade_versions

parents 83635909 5b475c22
......@@ -70,14 +70,6 @@
<key> <string>center</string> </key>
<value>
<list>
<string>my_title</string>
<string>my_reference</string>
<string>my_credit_account</string>
<string>my_gap_list</string>
<string>my_account_type</string>
<string>my_financial_section</string>
<string>my_destination_title_list</string>
<string>my_translated_validation_state_title</string>
<string>my_description</string>
</list>
</value>
......@@ -85,13 +77,23 @@
<item>
<key> <string>left</string> </key>
<value>
<list/>
<list>
<string>my_title</string>
<string>my_reference</string>
<string>my_gap_list</string>
<string>my_account_type</string>
<string>my_financial_section</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
<list>
<string>my_credit_account</string>
<string>my_destination_title_list</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
</dictionary>
......
......@@ -90,7 +90,7 @@ for line in line_list:
'source_function', 'destination_function',
'source_funding', 'destination_funding',
'source_payment_request', 'destination_payment_request',
'resource', 'product_line' ]:
'resource', 'product_line', 'string_index' ]:
if line.getProperty(prop) != context.getProperty(prop):
new_line.setProperty(prop, line.getProperty(prop))
......
......@@ -83,7 +83,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_importGapFileForm</string> </value>
<value> <string>CategoryTool_viewImportGapFileDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -91,7 +91,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Base_importGapFileForm</string> </value>
<value> <string>CategoryTool_viewImportGapFileDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......
......@@ -3372,25 +3372,6 @@ class TestTransactions(AccountingTestCase):
accounting_transaction.stop()
self.assertEqual('code-2001-1', accounting_transaction.getSourceReference())
def test_generate_sub_accounting_periods(self):
accounting_period_2007 = self.section.newContent(
portal_type='Accounting Period',
start_date=DateTime('2007/01/01'),
stop_date=DateTime('2007/12/31'),)
accounting_period_2007.start()
accounting_period_2007.AccountingPeriod_createSecondaryPeriod(
frequency='monthly', open_periods=1)
sub_period_list = sorted(accounting_period_2007.contentValues(),
key=lambda x:x.getStartDate())
self.assertEqual(12, len(sub_period_list))
first_period = sub_period_list[0]
self.assertEqual(DateTime(2007, 1, 1), first_period.getStartDate())
self.assertEqual(DateTime(2007, 1, 31), first_period.getStopDate())
self.assertEqual('2007-01', first_period.getShortTitle())
self.assertEqual('January', first_period.getTitle())
def test_SearchableText(self):
accounting_transaction = self._makeOne(title='A new Transaction',
description="A description",
......@@ -6123,3 +6104,70 @@ class TestAccountingAlarms(AccountingTestCase):
'{} has wrong grouping (4.0)'.format(payment.grouped_line.getRelativeUrl()),]),
sorted([x.getProperty('detail') for x in alarm.getLastActiveProcess().getResultList()]))
self.assertTrue(alarm.sense())
class TestAccountingPeriod(AccountingTestCase):
def test_generate_sub_accounting_periods(self):
accounting_period_2007 = self.section.newContent(
portal_type='Accounting Period',
start_date=DateTime('2007/01/01'),
stop_date=DateTime('2007/12/31'),)
accounting_period_2007.start()
accounting_period_2007.AccountingPeriod_createSecondaryPeriod(
frequency='monthly', open_periods=1)
sub_period_list = sorted(accounting_period_2007.contentValues(),
key=lambda x:x.getStartDate())
self.assertEqual(12, len(sub_period_list))
first_period = sub_period_list[0]
self.assertEqual(DateTime(2007, 1, 1), first_period.getStartDate())
self.assertEqual(DateTime(2007, 1, 31), first_period.getStopDate())
self.assertEqual('2007-01', first_period.getShortTitle())
self.assertEqual('January', first_period.getTitle())
def test_accounting_period_workflow_constraint(self):
first_accounting_period = self.section.newContent(
portal_type='Accounting Period',
start_date=DateTime('2021/01/01'),
stop_date=DateTime('2020/12/31'),)
with self.assertRaisesRegexp(ValidationFailed,
'Start date is after stop date'):
self.portal.portal_workflow.doActionFor(first_accounting_period, 'start_action')
# make first accounting period valid, for the full 2021 year
first_accounting_period.setStopDate(DateTime('2021/12/31'))
self.portal.portal_workflow.doActionFor(first_accounting_period, 'start_action')
self.tic()
# check dates don't overlap
second_accounting_period = self.section.newContent(
portal_type='Accounting Period',
start_date=DateTime('2021/01/01'),
stop_date=DateTime('2022/12/31'),)
with self.assertRaisesRegexp(ValidationFailed,
'2021/01/01 00:00:00 .* is already in an open accounting period.'):
self.portal.portal_workflow.doActionFor(second_accounting_period, 'start_action')
# check there are no "holes" between dates
second_accounting_period.setStartDate('2022/01/02')
with self.assertRaisesRegexp(ValidationFailed,
'Last opened period ends on 2021/12/31.*, this period starts on 2022/01/02.*. Accounting Periods must be consecutive.'):
self.portal.portal_workflow.doActionFor(second_accounting_period, 'start_action')
# edge case, when the end date of previous period is a DST swich, this should not block
first_accounting_period.setStopDate(DateTime('2021/10/31 00:00:00 Europe/Paris'))
second_accounting_period.setStartDate(DateTime('2021/11/01 00:00:00 Europe/Paris'))
self.portal.portal_workflow.doActionFor(second_accounting_period, 'start_action')
# reset first period to 2021 and second period 2022
first_accounting_period.setStopDate(DateTime('2021/12/31'))
second_accounting_period.setStartDate(DateTime('2022/01/01'))
second_accounting_period.setStopDate(DateTime('2022/12/31'))
# check also with more than 2 periods
third_accounting_period = self.section.newContent(
portal_type='Accounting Period',
start_date=DateTime('2023/01/01'),
stop_date=DateTime('2023/12/31'),)
self.portal.portal_workflow.doActionFor(third_accounting_period, 'start_action')
......@@ -12,27 +12,36 @@ stop_date = closing_period.getStopDate()
if start_date > stop_date:
raise ValidationFailed, translateString("Start date is after stop date.")
period_list = closing_period.getParentValue().searchFolder(
simulation_state=valid_state_list,
sort_on=[('delivery.start_date', 'asc')],
portal_type='Accounting Period')
period_list = [
x
for x in closing_period.getParentValue().contentValues(
portal_type="Accounting Period",
checked_permission="Access contents information",
)
if x.getSimulationState() in valid_state_list
]
for period in period_list:
period = period.getObject()
if period.getSimulationState() in valid_state_list:
if start_date <= period.getStopDate() and not stop_date <= period.getStartDate():
raise ValidationFailed, translateString(
"${date} is already in an open accounting period.",
mapping={'date': start_date})
if start_date <= period.getStopDate() and not stop_date <= period.getStartDate():
raise ValidationFailed, translateString(
"${date} is already in an open accounting period.",
mapping={'date': start_date})
if len(period_list) > 1:
last_period = period_list[-1].getObject()
if last_period.getId() == closing_period.getId():
last_period = period_list[-2].getObject()
if (start_date - last_period.getStopDate()) > 1:
previous_period = next(
iter(
sorted(
[x for x in period_list if x != closing_period],
key=lambda p: p.getStartDate(),
reverse=True,
)
),
None,
)
if previous_period is not None:
if (start_date - previous_period.getStopDate()) > 1.9:
raise ValidationFailed, translateString(
"Last opened period ends on ${last_openned_date},"+
" this period starts on ${this_period_start_date}."+
" Accounting Periods must be consecutive.",
mapping = { 'last_openned_date': last_period.getStopDate(),
mapping = { 'last_openned_date': previous_period.getStopDate(),
'this_period_start_date': start_date } )
......@@ -87,15 +87,27 @@ Test Account GAP Parallel listfield.
<!-- check also non editable mode -->
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/toggle_editable_mode" />
<tal:block metal:use-macro="here/Zuite_CommonTemplateForRenderjsUi/macros/wait_for_content_loaded" />
<tr>
<td>assertValue</td>
<td>subfield_field_my_gap_list_my_country/my_accounting_standards</td>
<td>my_country/my_accounting_standards/1</td>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_gap_list']//div[@data-gadget-scope='PARALLEL_SUB_FIELD_0']//label[@for='subfield_field_my_gap_list_my_country/my_accounting_standards' and text()='GAP - My Accounting Standards']</td>
<td></td>
</tr>
<tr>
<td>assertValue</td>
<td>subfield_field_my_gap_list_another_country/another_standards</td>
<td>another_country/another_standards/1</td>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_gap_list']//div[@data-gadget-scope='PARALLEL_SUB_FIELD_0']//p[text()='1 - Equity Accounts']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_gap_list']//div[@data-gadget-scope='PARALLEL_SUB_FIELD_1']//label[@for='subfield_field_my_gap_list_another_country/another_standards' and text()='GAP - Another Standards']</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@data-gadget-scope='field_my_gap_list']//div[@data-gadget-scope='PARALLEL_SUB_FIELD_1']//p[text()='1 - Dummy Account']</td>
<td></td>
</tr>
</tbody></table>
......
......@@ -128,7 +128,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSection_viewLoyaltyRequest</string> </value>
<value> <string>WebSection_viewLoyaltyRequestDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -136,7 +136,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>WebSection_viewLoyaltyRequest</string> </value>
<value> <string>WebSection_viewLoyaltyRequestDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......
......@@ -163,7 +163,7 @@
</item>
<item>
<key> <string>custom_render_method_id</string> </key>
<value> <string>WebSection_viewLoyaltyRequest</string> </value>
<value> <string>WebSection_viewLoyaltyRequestDialog</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......
<tal:block xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<tal:block tal:condition="here/portal_skins/updateSkinCookie | nothing"
tal:define="dummy here/setupCurrentSkin;" />
<tal:block tal:define="response request/RESPONSE;
mtool here/portal_membership;
isAnon mtool/isAnonymousUser|nothing;">
<tal:block tal:condition="isAnon">
<tal:block tal:define="dummy python: response.expireCookie('__ac', path='/');
is_user_account_blocked python: request.get('is_user_account_blocked', False);
is_user_account_password_expired python: request.get('is_user_account_password_expired', False);">
<!-- Login and/or password is incorrect. -->
<tal:block tal:condition="python: not is_user_account_blocked and not is_user_account_password_expired">
<tal:block tal:define="url python: '%s/login_form?portal_status_message=%s' % (here.absolute_url(), here.Base_translateString('Login and/or password is incorrect.'));
url python: request.get('came_from') and '%s&amp;came_from=%s' % (url, request['came_from']) or url;
dummy python: response.redirect(url);"/>
</tal:block>
<!-- Login is blocked. -->
<tal:block tal:condition="is_user_account_blocked">
<tal:block tal:define="url python: '%s/login_form?portal_status_message=%s' % (here.absolute_url(), here.Base_translateString('Account is blocked.'));
url python: request.get('came_from') and '%s&amp;came_from=%s' % (url, request['came_from']) or url;
dummy python: response.redirect(url);"/>
</tal:block>
<!-- Password is expired permanently. -->
<tal:block tal:condition="is_user_account_password_expired">
<tal:block tal:define="message python: {False: 'Password is expired.',
True: 'Password is expired. You will soon receive an email with details about how you can recover it.'}.get(here.getPortalObject().portal_preferences.isPreferredSystemRecoverExpiredPassword());
url python: '%s/login_form?portal_status_message=%s' % (here.absolute_url(), here.Base_translateString(message));
url python: request.get('came_from') and '%s&amp;came_from=%s' % (url, request['came_from']) or url;
dummy python: response.redirect(url);"/>
</tal:block>
</tal:block>
</tal:block>
<tal:block tal:condition="not: isAnon"
tal:define="is_user_account_password_expired_expire_date python:request.get('is_user_account_password_expired_expire_date', 0);">
<!-- Password will expire soon just warn user ? -->
<tal:block tal:condition="is_user_account_password_expired_expire_date">
<tal:block tal:define="came_from python: request.get('came_from') or here.absolute_url();
dummy python: response.redirect('%s/ERP5Site_viewNewPersonCredentialUpdateDialog?portal_status_message=%s&amp;cancel_url=%s' %(came_from, here.Base_translateString('Your password will expire at %s. You are advised to change it as soon as possible.' %context.Base_FormatDate(is_user_account_password_expired_expire_date, hour_minute=1)), came_from));" />
</tal:block>
<tal:block tal:condition="not: is_user_account_password_expired_expire_date">
<tal:block tal:define="came_from python: request.get('came_from') or here.absolute_url();
dummy python: response.redirect(came_from);" />
</tal:block>
</tal:block>
</tal:block>
</tal:block>
\ No newline at end of file
......@@ -31,9 +31,11 @@
from functools import partial
import unittest
import urllib
import urlparse
from StringIO import StringIO
import time
import httplib
import mock
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.Document import newTempBase
......@@ -710,7 +712,10 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
basic='test-05:used_ALREADY_1234',
)
response = publish()
self.assertTrue(response.getHeader("Location").endswith("login_form?portal_status_message=Account is blocked."))
redirect_url = urlparse.urlparse(response.getHeader("Location"))
self.assertEqual(redirect_url.path, '{}/login_form'.format(portal.absolute_url_path()))
redirect_url_params = urlparse.parse_qsl(redirect_url.query)
self.assertEqual(redirect_url_params, [('portal_status_message', 'Account is blocked.')] )
# test expire password message, first unblock it
login.Login_unblockLogin()
......@@ -718,7 +723,10 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self.tic()
self._clearCache()
response = publish()
self.assertTrue(response.getHeader("Location").endswith("login_form?portal_status_message=Password is expired."))
redirect_url = urlparse.urlparse(response.getHeader("Location"))
self.assertEqual(redirect_url.path, '{}/login_form'.format(portal.absolute_url_path()))
redirect_url_params = urlparse.parse_qsl(redirect_url.query)
self.assertEqual(redirect_url_params, [('portal_status_message', 'Password is expired.')] )
self.assertTrue(login.isPasswordExpired())
# test we're redirected to update password due to soon expire
......@@ -727,9 +735,11 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self.tic()
self._clearCache()
response = publish()
self.assertTrue('Your password will expire' in response.getHeader("Location"))
self.assertTrue('You are advised to change it as soon as possible' in response.getHeader("Location"))
redirect_url = urlparse.urlparse(response.getHeader("Location"))
self.assertEqual(redirect_url.path, '{}/ERP5Site_viewNewPersonCredentialUpdateDialog'.format(portal.absolute_url_path()))
redirect_url_params = urlparse.parse_qs(redirect_url.query)
self.assertIn('Your password will expire', redirect_url_params['portal_status_message'][0])
self.assertIn('You are advised to change it as soon as possible', redirect_url_params['portal_status_message'][0])
# test proper login
preference.setPreferredPasswordLifetimeExpireWarningDuration(12)
......@@ -741,6 +751,18 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
)
self.assertTrue('Welcome to ERP5' in response.getBody())
# test external redirection prevention
response = self.publish(
portal.absolute_url_path() + '/logged_in',
basic='test-05:used_ALREADY_1234',
stdin=StringIO(urllib.urlencode({'came_from': 'https://www.erp5.com'})),
request_method='POST',
)
redirect_url = urlparse.urlparse(response.getHeader("Location"))
self.assertEqual(redirect_url.path, portal.absolute_url_path())
redirect_url_params = urlparse.parse_qsl(redirect_url.query)
self.assertEqual(redirect_url_params, [('portal_status_message', 'Redirection to an external site prevented.')] )
def test_ExpireOldAuthenticationEventList(self):
"""
Check that expiring old Authentication Event list works.
......@@ -793,39 +815,45 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self.tic()
reset_key = self.portal.portal_password.getResetPasswordKey(user_login=self.id())
ret = self.publish(
'%s/portal_password' % self.portal.getPath(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PasswordTool_viewResetPassword',
'dialog_method': 'PasswordTool_changeUserPassword',
'field_user_login': self.id(),
'field_your_password': 'alice',
'field_password_confirm': 'alice',
'field_your_password_key': reset_key,
})),
request_method="POST",
handle_errors=False)
def submit_reset_password_dialog(new_password):
return self.publish(
'%s/portal_password' % self.portal.getPath(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PasswordTool_viewResetPassword',
'dialog_method': 'PasswordTool_changeUserPassword',
'field_user_login': self.id(),
'field_your_password': new_password,
'field_password_confirm': new_password,
'field_your_password_key': reset_key,
})),
request_method="POST",
handle_errors=False)
ret = submit_reset_password_dialog('alice')
self.assertEqual(httplib.OK, ret.getStatus())
self.assertIn(
'<span class="error">You can not use any parts of your '
'first and last name in password.</span>',
ret.getBody())
# the messages are translated
default_gettext = self.portal.Localizer.erp5_ui.gettext
def gettext(message, **kw):
if message == 'You can not use any parts of your first and last name in password.':
return u'Yöü can not ... translated'
assert message != u'Yöü can not ... translated'
return default_gettext(message, **kw)
with mock.patch.object(self.portal.Localizer.erp5_ui.__class__, 'gettext', side_effect=gettext):
ret = submit_reset_password_dialog('alice')
self.assertEqual(httplib.OK, ret.getStatus())
self.assertIn(
'<span class="error">Yöü can not ... translated</span>',
ret.getBody())
# now with a password complying to the policy
ret = self.publish(
'%s/portal_password' % self.portal.getPath(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PasswordTool_viewResetPassword',
'dialog_method': 'PasswordTool_changeUserPassword',
'field_user_login': self.id(),
'field_your_password': 'ok',
'field_password_confirm': 'ok',
'field_your_password_key': reset_key,
})),
request_method="POST",
handle_errors=False)
ret = submit_reset_password_dialog('ok')
self.assertEqual(httplib.FOUND, ret.getStatus())
self.assertTrue(ret.getHeader('Location').endswith(
'/login_form?portal_status_message=Password+changed.'))
......@@ -841,25 +869,43 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
self._clearCache()
self.tic()
def submit_change_password_dialog(new_password):
return self.publish(
'%s/portal_preferences' % self.portal.getPath(),
basic='%s:current' % self.id(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PreferenceTool_viewChangePasswordDialog',
'dialog_method': 'PreferenceTool_setNewPassword',
'field_your_current_password': 'current',
'field_your_new_password': new_password,
'field_password_confirm': new_password,
})),
request_method="POST",
handle_errors=False)
# too short password is refused
ret = self.publish(
'%s/portal_preferences' % self.portal.getPath(),
basic='%s:current' % self.id(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PreferenceTool_viewChangePasswordDialog',
'dialog_method': 'PreferenceTool_setNewPassword',
'field_your_current_password': 'current',
'field_your_new_password': 'short',
'field_password_confirm': 'short',
})),
request_method="POST",
handle_errors=False)
ret = submit_change_password_dialog('short')
self.assertEqual(httplib.OK, ret.getStatus())
self.assertIn(
'<span class="error">Too short.</span>',
ret.getBody())
# the messages are translated
default_gettext = self.portal.Localizer.erp5_ui.gettext
def gettext(message, **kw):
if message == 'Too short.':
return u'Töü short ... translated'
assert message != u'Töü short ... translated'
return default_gettext(message, **kw)
with mock.patch.object(self.portal.Localizer.erp5_ui.__class__, 'gettext', side_effect=gettext):
ret = submit_change_password_dialog('short')
self.assertEqual(httplib.OK, ret.getStatus())
self.assertIn(
'<span class="error">Töü short ... translated</span>',
ret.getBody())
# if for some reason, PreferenceTool_setNewPassword is called directly,
# the password policy is also checked, so this cause an unhandled exception.
self.login(person.getUserId())
......@@ -870,19 +916,7 @@ class TestAuthenticationPolicy(ERP5TypeTestCase):
new_password='short')
# long enough password is accepted
ret = self.publish(
'%s/portal_preferences' % self.portal.getPath(),
basic='%s:current' % self.id(),
stdin=StringIO(urllib.urlencode({
'Base_callDialogMethod:method': '',
'dialog_id': 'PreferenceTool_viewChangePasswordDialog',
'dialog_method': 'PreferenceTool_setNewPassword',
'field_your_current_password': 'current',
'field_your_new_password': 'long_enough_password',
'field_password_confirm': 'long_enough_password',
})),
request_method="POST",
handle_errors=False)
ret = submit_change_password_dialog('long_enough_password')
# When password reset is succesful, user is logged out
self.assertEqual(httplib.FOUND, ret.getStatus())
self.assertEqual(self.portal.portal_preferences.absolute_url(),
......
......@@ -77,7 +77,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/ExternalIndentifier_view</string> </value>
<value> <string>string:${object_url}/ExternalIdentifier_view</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -71,7 +71,7 @@ class EncryptedPasswordMixin:
# not a policy so basically all passwords are accceptable
return True
if not self.isPasswordValid(value):
raise ValueError("Password value doest not comply with password policy")
raise ValueError("Password does not comply with password policy")
def checkUserCanChangePassword(self):
if not _checkPermission(Permissions.SetOwnPassword, self):
......
now = DateTime()
return (
context.getValidationState() == 'open'
and (not context.hasStartDate() or context.getStartDate() <= now)
and (not context.hasStopDate() or context.getStopDate() >= now)
)
......@@ -50,11 +50,11 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UserAccountWorkflow_verifyUserCreationInput</string> </value>
<value> <string>Assignment_isEffective</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -99,15 +99,16 @@
<string>my_title</string>
<string>image_view</string>
<string>my_file</string>
<string>my_filename</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
<item>
<key> <string>right (Publication Information)</string> </key>
<value>
<list/>
<list>
<string>my_filename</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
</dictionary>
......
......@@ -93,7 +93,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ExternalIndentifier_view</string> </value>
<value> <string>ExternalIdentifier_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......
......@@ -16,7 +16,7 @@ login = getSecurityManager().getUser().getLoginValue()
if login is not None:
validation_message_list = login.analyzePassword(editor)
if validation_message_list:
message = u' '.join([str(x) for x in validation_message_list])
message = ' '.join([str(x) for x in validation_message_list])
raise ValidationError('external_validator_failed', context, error_text=message)
return 1
kwargs = state_change['kwargs']
person = state_change['object']
if not person.hasUserId():
person.edit(user_id=kwargs['reference'])
person.newContent(
portal_type='ERP5 Login',
password=kwargs['password'],
reference=kwargs['reference']).validate()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>UserAccountWorkflow_createUser</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from Products.DCWorkflow.DCWorkflow import ValidationFailed
from Products.ERP5Type.Message import translateString
kwargs = state_change['kwargs']
password = kwargs['password']
password_confirm = kwargs['password_confirm']
if password != password_confirm:
raise ValidationFailed(translateString('Passwords do not match.'))
reference = kwargs['reference']
if not reference:
raise ValidationFailed(translateString('User Login is not specified.'))
......@@ -86,8 +86,8 @@
<value>
<list>
<string>my_source</string>
<string>my_quantity</string>
<string>my_resource_title</string>
<string>my_translated_simulation_state_title</string>
</list>
</value>
</item>
......@@ -97,7 +97,7 @@
<list>
<string>my_start_date</string>
<string>my_destination</string>
<string>my_quantity</string>
<string>my_translated_simulation_state_title</string>
</list>
</value>
</item>
......
......@@ -32,7 +32,7 @@
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
<value> <string>erp5_certificate_authority</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
......
......@@ -2,4 +2,4 @@ certificate = context.getCertificate()
request = context.REQUEST
request.set('your_certificate', certificate['certificate'])
request.set('your_key', certificate['key'])
return context.Person_getCertificateForm()
return context.Person_viewCertificateDialog()
......@@ -111,7 +111,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_getCertificateForm</string> </value>
<value> <string>Person_viewCertificateDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -119,7 +119,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Person_getCertificateForm</string> </value>
<value> <string>Person_viewCertificateDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2020 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# 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 2
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from zope.interface import Interface
class ISpreadsheetConfiguratorItem(Interface):
"""Configurator Item using spreadsheet as data source for configuration
"""
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interface Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>ISpreadsheetConfiguratorItem</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interface.erp5.ISpreadsheetConfiguratorItem</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Interface Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -82,7 +82,9 @@
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
<tuple>
<string>ISpreadsheetConfiguratorItem</string>
</tuple>
</value>
</item>
<item>
......
......@@ -64,7 +64,9 @@
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
<tuple>
<string>ISpreadsheetConfiguratorItem</string>
</tuple>
</value>
</item>
<item>
......
......@@ -110,7 +110,7 @@
<string>my_comment</string>
<string>my_translated_simulation_state_title</string>
<string>my_translated_validation_state_title</string>
<string>my_configuration_state</string>
<string>my_translated_configuration_state_title</string>
</list>
</value>
</item>
......
......@@ -8,7 +8,7 @@
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_configuration_state</string> </value>
<value> <string>my_translated_configuration_state_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......
interface.erp5.IConfiguratorItem
\ No newline at end of file
interface.erp5.IConfiguratorItem
interface.erp5.ISpreadsheetConfiguratorItem
\ No newline at end of file
......@@ -97,14 +97,16 @@
<key> <string>left</string> </key>
<value>
<list>
<string>my_translated_content_translation_state_title</string>
<string>my_title</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
<list>
<string>my_translated_content_translation_state_title</string>
</list>
</value>
</item>
</dictionary>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -1181,10 +1181,12 @@ class TestERP5Base(ERP5TypeTestCase):
site='distibution/tokyo')
self.assertNotEquals(None, assignment.getGroupValue())
assignment.open()
self.portal.portal_workflow.doActionFor(person, 'create_user_action',
reference='user_login',
password='pass',
password_confirm='pass')
login = person.newContent(
portal_type="ERP5 Login",
reference="user_login",
password="pass",
)
login.validate()
self.tic()
# a user is created
......
......@@ -38,7 +38,7 @@ from AccessControl import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager
from Acquisition import aq_base
from DateTime import DateTime
from _mysql_exceptions import ProgrammingError
from MySQLdb import ProgrammingError
from OFS.ObjectManager import ObjectManager
from Products.CMFActivity import ActivityTool
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
......
......@@ -32,7 +32,7 @@ import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import createZODBPythonScript
from _mysql_exceptions import ProgrammingError
from MySQLdb import ProgrammingError
class TestIdTool(ERP5TypeTestCase):
......
......@@ -9,7 +9,13 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>css_class</string>
<string>default</string>
<string>editable</string>
<string>enabled</string>
<string>title</string>
</list>
</value>
</item>
<item>
......@@ -50,6 +56,22 @@
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -69,9 +91,25 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string>page</string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>text_content</string> </value>
<value> <string>my_text_content</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
......@@ -81,10 +119,40 @@
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Page Content</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/asStrippedHTML</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>not:here/isExternalDocument</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -6,6 +6,7 @@ person = context.getDestinationDecisionValue(portal_type="Person")
# Person Mapping
person_mapping = (
# (credential, person)
('social_title', 'social_title'),
('first_name', 'first_name'),
('last_name', 'last_name'),
('gender', 'gender'),
......
......@@ -111,6 +111,7 @@
<key> <string>left (Personal Information)</string> </key>
<value>
<list>
<string>my_social_title</string>
<string>my_first_name</string>
<string>my_last_name</string>
<string>my_gender</string>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_social_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_category</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Title</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -73,7 +73,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Event_viewDocumentFastInputList</string> </value>
<value> <string>string:${object_url}/Event_viewDocumentFastInputDialog</string> </value>
</item>
</dictionary>
</pickle>
......
"""Generic script of Entity_addEvent
"""Generic script to add event
It creates new Event for any context which become follow_up of created Event.
Connected user is source (outgoing direction)
......
from erp5.component.module.Log import log
log('Obsoleted, please use Base_addEvent (with Base_viewAddEventDialog) instead')
return context.Base_addEvent(title, direction, portal_type, resource, **kw)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Entity_addEvent</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>your_title</string>
<string>your_portal_type</string>
<string>your_direction</string>
<string>your_resource</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Entity_addEventDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Entity_addEventDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Create New Event</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>your_portal_type</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>your_portal_type</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewCRMFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -117,7 +117,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Event_viewDocumentFastInputList</string> </value>
<value> <string>Event_viewDocumentFastInputDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......@@ -125,7 +125,7 @@
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Event_viewDocumentFastInputList</string> </value>
<value> <string>Event_viewDocumentFastInputDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
......
......@@ -28,7 +28,6 @@
<key> <string>transitions</string> </key>
<value>
<tuple>
<string>create_ticket</string>
<string>create_ticket_action</string>
<string>deliver</string>
<string>deliver_action</string>
......
......@@ -22,10 +22,6 @@
<key> <string>actbox_url</string> </key>
<value> <string>%(content_url)s/Event_viewCreateTicketWorkflowActionDialog?workflow_action=create_ticket_action</string> </value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value> <string>create_ticket</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Disabled action.</string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ExternalWebPage_viewWebPageList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>ExternalWebSite_viewSubpages</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Subpages</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -102,7 +102,6 @@
<string>my_file</string>
<string>my_filename</string>
<string>my_translated_portal_type</string>
<string>my_translated_external_processing_state_title</string>
<string>my_revision</string>
</list>
</value>
......@@ -125,6 +124,7 @@
<string>my_function_list</string>
<string>my_follow_up_title_list</string>
<string>my_publication_section_list</string>
<string>my_translated_external_processing_state_title</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
......
......@@ -110,7 +110,6 @@
<string>my_file</string>
<string>my_filename</string>
<string>my_translated_portal_type</string>
<string>my_translated_external_processing_state_title</string>
<string>my_revision</string>
</list>
</value>
......@@ -125,6 +124,7 @@
<string>my_function_list</string>
<string>my_follow_up_title_list</string>
<string>my_publication_section_list</string>
<string>my_translated_external_processing_state_title</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
......
......@@ -110,7 +110,6 @@
<string>my_file</string>
<string>my_filename</string>
<string>my_thumbnail</string>
<string>my_translated_external_processing_state_title</string>
<string>my_revision</string>
</list>
</value>
......@@ -125,6 +124,7 @@
<string>my_function_list</string>
<string>my_follow_up_title_list</string>
<string>my_publication_section_list</string>
<string>my_translated_external_processing_state_title</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
......
......@@ -10,6 +10,7 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>css_class</string>
<string>editable</string>
</list>
</value>
......@@ -75,6 +76,10 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>css_class</string> </key>
<value> <string>page</string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
......
......@@ -73,7 +73,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/Event_viewDocumentFastInputList</string> </value>
<value> <string>string:${object_url}/Event_viewDocumentFastInputDialog</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
......@@ -75,7 +75,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_viewConflicted</string> </value>
<value> <string>string:${object_url}/BusinessTemplate_viewConflictedDialog</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......@@ -75,7 +75,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_viewCreateWorkingCopy</string> </value>
<value> <string>string:${object_url}/BusinessTemplate_viewCreateWorkingCopyDialog</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
<string>action_type/object_onlyxhtml_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
<value> <string>object_onlyxhtml_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_onlyjio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_onlyjio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>git_commit_action</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Manage portal</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>4.5</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Git</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_viewVcsStatusDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: here.getInstallationState() not in (\'installed\', \'replaced\') and here.isVcsType(\'git\')</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -73,7 +73,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_renameProxyFieldDialog</string> </value>
<value> <string>string:${object_url}/BusinessTemplate_viewRenameProxyFieldDialog</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -16,13 +16,13 @@
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
<string>action_type/object_jio_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
<value> <string>object_jio_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
......
......@@ -32,7 +32,6 @@ from AccessControl.SecurityInfo import ModuleSecurityInfo
from Acquisition import aq_base
from DateTime import DateTime
from Products.ERP5Type.Message import translateString
from ZTUtils import make_query
from erp5.component.module.WorkingCopy import \
WorkingCopy, NotAWorkingCopyError, NotVersionedError, Dir, File, selfcached
......@@ -321,10 +320,8 @@ class Git(WorkingCopy):
return self.git('rev-parse', '--short', 'HEAD') + '+'
return self.git('rev-parse', 'HEAD')
def commit(self, changelog, added=(), modified=(), removed=()):
def commit(self, changelog, push, added=(), modified=(), removed=()):
context = self.aq_parent
request = context.REQUEST
push = request.get('push')
reset = 1
if push:
# if we can't push because we are not up-to-date, we'll either 'merge' or
......@@ -390,9 +387,9 @@ class Git(WorkingCopy):
portal_status_message = translateString(
'Files committed successfully in revision ${revision}',
mapping=dict(revision=head))
return request.RESPONSE.redirect('%s/view?%s' % (
context.absolute_url_path(),
make_query(portal_status_message=portal_status_message)))
return context.Base_redirect('view', keep_items={
'portal_status_message': portal_status_message
})
def log(self, path='.'):
log = []
......
......@@ -90,7 +90,6 @@
<string>my_causality_title</string>
<string>my_language</string>
<string>my_title</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
......@@ -100,6 +99,7 @@
<list>
<string>my_description</string>
<string>my_comment</string>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
......
......@@ -116,7 +116,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>BusinessTemplate_renameProxyFieldDialog</string> </value>
<value> <string>BusinessTemplate_viewRenameProxyFieldDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment