Skip to content

Commit

Permalink
Merge pull request #671 from ecino/10.0-emanuel
Browse files Browse the repository at this point in the history
Communication revision improvements
  • Loading branch information
ecino authored May 9, 2018
2 parents b6e9c41 + 0aee7ca commit 6afc458
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 61 deletions.
5 changes: 5 additions & 0 deletions partner_communication_revision/models/communication_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@ def new_proposition(self):
'target': 'current',
'context': self.env.context
}

@api.multi
def open_translation_view(self):
return self.env['ir.translation'].translate_fields(
'mail.template', self.email_template_id.id, 'body_html')
17 changes: 10 additions & 7 deletions partner_communication_revision/models/communication_keyword.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class CommunicationKeyword(models.Model):
)
type = fields.Selection(
[('if', 'If Condition'),
('var', 'Keyword'),
('var', 'Variable'),
('code', 'Keyword'),
('for', 'Loop'),
('for_ul', 'Loop'),
Expand Down Expand Up @@ -115,7 +115,7 @@ def _compute_short_code(self):
for keyword in self:
if keyword.type == 'var':
raw = keyword.raw_code.split('=')[0].split('% set ')[-1]
keyword.short_code = raw.strip()
keyword.short_code = 'var-' + raw.strip().replace('.', '-')
else:
raw = keyword.raw_code
if keyword.type in ('if', 'for', 'for_ul'):
Expand Down Expand Up @@ -211,15 +211,18 @@ def create(self, vals):
@api.multi
def unlink(self):
# Update indexes
other_kw = self.env[self._name]
for keyword in self:
other_kw = self.search([
other_kw |= self.search([
('type', '=', keyword.type),
('revision_id', '=', keyword.revision_id.id),
('index', '>', keyword.index)
('index', '>', keyword.index),
('id', 'not in', self.ids)
])
for kw in other_kw:
kw.index -= 1
return super(CommunicationKeyword, self).unlink()
res = super(CommunicationKeyword, self).unlink()
for keyword in other_kw.sorted('index'):
keyword.index -= 1
return res

@api.multi
def toggle_edit_value(self):
Expand Down
78 changes: 53 additions & 25 deletions partner_communication_revision/models/communication_revision.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ class CommunicationRevision(models.Model):
state = fields.Selection([
('pending', 'Pending'),
('submit', 'Submitted'),
('corrected', 'Corrected'),
('approved', 'Approved'),
('active', 'Active'),
], default='active')
is_master_version = fields.Boolean()
subject = fields.Char()
subject_correction = fields.Char()
body_html = fields.Html(related='config_id.email_template_id.body_html')
raw_template_edit_mode = fields.Boolean()
simplified_text = fields.Html(sanitize=False)
user_id = fields.Many2one('res.users', 'Responsible', domain=[
('share', '=', False)], track_visibility='onchange')
Expand All @@ -85,6 +87,7 @@ class CommunicationRevision(models.Model):
keyword_ids = fields.One2many(
'partner.communication.keyword', 'revision_id', 'Keywords'
)
show_all_keywords = fields.Boolean()
edit_keyword_ids = fields.One2many(
'partner.communication.keyword',
compute='_compute_keyword_ids', inverse='_inverse_keyword_ids',
Expand All @@ -103,7 +106,6 @@ class CommunicationRevision(models.Model):
is_proposer = fields.Boolean(compute='_compute_allowed')
is_corrector = fields.Boolean(compute='_compute_allowed')
display_name = fields.Char(compute='_compute_display_name')
is_corrected = fields.Boolean()

_sql_constraints = [
('unique_revision', 'unique(config_id,lang)',
Expand All @@ -129,11 +131,16 @@ def select_lang(self):
def _compute_keyword_ids(self):
for revision in self:
revision.edit_keyword_ids = revision.keyword_ids.filtered(
lambda k: k.type == 'code' and k.is_visible)
lambda k: (
(revision.show_all_keywords and k.type in ('code', 'var'))
or k.type == 'code'
) and (revision.show_all_keywords or k.is_visible))
revision.if_keyword_ids = revision.keyword_ids.filtered(
lambda k: k.type == 'if' and k.is_visible)
lambda k: k.type == 'if' and (revision.show_all_keywords or
k.is_visible))
revision.for_keyword_ids = revision.keyword_ids.filtered(
lambda k: 'for' in k.type and k.is_visible)
lambda k: 'for' in k.type and (revision.show_all_keywords or
k.is_visible))

@api.multi
def _inverse_keyword_ids(self):
Expand Down Expand Up @@ -344,14 +351,20 @@ def validate_correction(self):

return self.with_context(body=body, subject=subject)._open_validation()

@api.multi
def edit_correction(self):
return self.write({
'state': 'pending',
'proposition_text': self.proposition_correction,
'proposition_correction': False
})

@api.multi
def discard_correction(self):
subject = '[{}] Revision approved'.format(self.display_name)
body = 'The original text for {} was kept. Proposed ' \
'corrections were discarded.'.format(self.display_name)
if not self.is_master_version:
self.approve(subject, body)
return self.with_context(body=body, subject=subject)._open_validation()
return self.write({
'state': 'pending',
'proposition_correction': False
})

@api.multi
def approve(self, subject=None, body=None):
Expand All @@ -361,7 +374,6 @@ def approve(self, subject=None, body=None):
'state': 'approved',
'compare_text': False,
'compare_subject': False,
'is_corrected': False
})
subject = self._context.get('subject', subject)
body = self._context.get('body', body)
Expand Down Expand Up @@ -406,8 +418,22 @@ def onchange_compare_lang(self):

@api.multi
def open_translation_view(self):
return self.env['ir.translation'].translate_fields(
'mail.template', self.config_id.email_template_id.id, 'body_html')
# Trick to avoid overriding raw template text changes
self.raw_template_edit_mode = True
return self.config_id.open_translation_view()

@api.multi
def reload_text(self):
text = self.with_context(lang=self.lang).body_html
self.raw_template_edit_mode = False
self.with_context(
no_update=True).simplified_text = self._simplify_text(text)

@api.multi
def toggle_all_keywords(self):
for record in self:
record.show_all_keywords = not record.show_all_keywords
return True

##########################################################################
# PRIVATE METHODS #
Expand Down Expand Up @@ -436,9 +462,10 @@ def _open_revision(self, form_view_mode=None):
:param form_view_mode: Specify a form view.
:return: action for opening the revision view
"""
text = self.with_context(lang=self.lang).body_html
self.with_context(
no_update=True).simplified_text = self._simplify_text(text)
# We don't need to update keywords when accessing the proposition
# text (config id in context for that case)
if not self.env.context.get('config_id'):
self.reload_text()
form_view = 'partner_communication_revision.revision_form'
if form_view_mode:
form_view += '_' + form_view_mode
Expand Down Expand Up @@ -562,7 +589,8 @@ def _replace_if(self, text, nested_position, keyword_number=1):
:return: simplified text without the if code, keywords found
"""
# Scan for non-nested % if, % else codes
if_pattern = re.compile(r'(% if .*?:)(.*?)(% endif)', flags=re.DOTALL)
if_pattern = re.compile(r'(% if .*?:$)(.*?)(% endif)',
flags=re.DOTALL | re.MULTILINE)
simple_text = text
keywords = self.env['partner.communication.keyword']
for match in if_pattern.finditer(text, overlapped=True):
Expand Down Expand Up @@ -620,17 +648,17 @@ def _replace_for(self, text, nested_position, keyword_number=1):
:return: simplified text without the if code, keywords found
"""
# Regex for finding text wrapped in loops
loop_regex = r'(% for .*?:)(.*?)(% endfor)'
ul_loop_regex = r'(?:<ul[^<]*?)(% for .*?:)(.*?)(% endfor)(.*?</ul>)'
loop_regex = r'(% for .*?:$)(.*?)(% endfor)'
ul_loop_regex = r'(?:<ul[^<]*?)(% for .*?:$)(.*?)(% endfor)(.*?</ul>)'

# First scan for ul_loops
for_pattern = re.compile(ul_loop_regex, flags=re.DOTALL)
for_pattern = re.compile(ul_loop_regex, flags=re.DOTALL | re.MULTILINE)
simple_text, found_keywords = self._replace_for_type(
text, nested_position, keyword_number, 'for_ul', for_pattern)
keyword_number += len(found_keywords)

# Then scan for regular loops
for_pattern = re.compile(loop_regex, flags=re.DOTALL)
for_pattern = re.compile(loop_regex, flags=re.DOTALL | re.MULTILINE)
simple_text, keywords = self._replace_for_type(
simple_text, nested_position, keyword_number, 'for', for_pattern)
found_keywords |= keywords
Expand Down Expand Up @@ -687,12 +715,12 @@ def _enhance_text(self):
html_text = PyQuery(self.simplified_text.replace('\n', ''))

def sort_keywords(kw):
# Replace first if-clause, then for-clause, then var, then code
# Replace first if/for-clauses, then var, then code
index = kw.position
if kw.type == 'if':
index += 3*len(self.body_html) * kw.nested_position
elif 'for' in kw.type:
if kw.type == 'if' or 'for' in kw.type:
index += 2*len(self.body_html) * kw.nested_position
# Take if and for in the appearing order in the text
index -= kw.position
elif kw.type == 'var':
index += len(self.body_html)
return index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
<field name="state" widget="statusbar"/>
</header>
</xpath>
<button name="toggle_active" position="before">
<button class="oe_stat_button" name="open_translation_view" icon="fa-edit" string="Edit raw translations" type="object" groups="base.group_system"/>
</button>
<xpath expr="//sheet">
<group string="Revisions">
<group colspan="2">
<field name="revision_number"/>
<field name="revision_date"/>
<field name="revision_ids" context="{'default_config_id': id, 'form_view_ref': 'partner_communication_revision.revision_simplified_form'}">
<tree colors="blue:state in ('pending','submit');green:state=='approved'">
<tree colors="blue:state in ('pending','submit','corrected');green:state=='approved'">
<field name="config_id" invisible="1"/>
<field name="lang"/>
<field name="user_id"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<tree create="false"
colors="darkblue:color=='darkblue';darkred:color=='darkred';darkgreen:color=='darkgreen';darkslateblue:color=='darkslateblue';firebrick:color=='firebrick';mediumorchid:color=='mediumorchid';orangered:color=='orangered';saddlebrown:color=='saddlebrown';seagreen:color=='seagreen';tomato:color=='tomato';darkslategrey:color=='darkslategrey';blueviolet:color=='blueviolet';burlywood:color=='burlywood';cadetblue:color=='cadetblue';coral:color=='coral';darksalmon:color=='darksalmon';goldenrod:color=='goldenrod'">
<field name="color" invisible="1"/>
<field name="type"/>
<field name="short_code"/>
<field name="name" string="Description"/>
</tree>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,21 @@
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" name="open_preview" icon="fa-search-plus" string="Preview" type="object"/>
<button class="oe_stat_button" name="open_translation_view" icon="fa-edit" string="Edit template" type="object"/>
<button class="oe_stat_button" name="open_translation_view" icon="fa-edit" string="Edit template" type="object" groups="base.group_system"/>
<button class="oe_stat_button" name="reload_text" icon="fa-refresh" string="Reload text" type="object" attrs="{'invisible': [('raw_template_edit_mode','=',False)]}"/>
</div>
<field name="raw_template_edit_mode" invisible="1"/>
<field name="proposition_text" groups="base.group_erp_manager"/>
<hr groups="base.group_erp_manager"/>
<field name="simplified_text" widget="html"/>
<button name="refresh_text" type="object" string="Refresh text" class="oe_highlight sht_refresh_button"/>
<field name="simplified_text" widget="html" attrs="{'readonly': [('raw_template_edit_mode','=',True)]}"/>
<button name="toggle_all_keywords" type="object" class="oe_stat_button">
<field name="show_all_keywords" widget="boolean_button" options='{"terminology": {
"string_true": "All keywords",
"string_false": "Hidden keywords",
"hover_true": "Hide unused keywords",
"hover_false": "Show all keywords"}}'/>
</button>
<button name="refresh_text" type="object" string="Update text" class="sht_refresh_button"/>
<group>
<field name="if_keyword_ids" context="{'tree_view_ref': 'partner_communication_revision.revision_keyword_tree_if'}"/>
<field name="edit_keyword_ids" context="{'tree_view_ref': 'partner_communication_revision.revision_keyword_tree'}"/>
Expand All @@ -49,7 +58,7 @@
<button class="oe_stat_button" name="open_preview" icon="fa-search-plus" string="Preview" type="object"/>
</div>
<field name="simplified_text" widget="html" readonly="1"/>
<button name="refresh_text" type="object" string="Refresh text" class="oe_highlight sht_refresh_button"/>
<button name="refresh_text" type="object" string="Update text" class="oe_highlight sht_refresh_button"/>
<group>
<field name="if_keyword_ids" context="{'tree_view_ref': 'partner_communication_revision.revision_keyword_tree_if'}"/>
</group>
Expand All @@ -67,13 +76,20 @@
<header>
<field name="is_proposer" invisible="1"/>
<field name="is_corrector" invisible="1"/>
<field name="is_corrected" invisible="1"/>
<field name="state" widget="statusbar"/>
<!-- Proposition to submit -->
<button type="object" name="submit_proposition" string="Submit proposition" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'pending'),('is_proposer', '=', False)]}"/>

<!-- Proposition to Approve / Corrections to submit-->
<button type="object" name="validate_proposition" string="Validate proposition" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'submit'),('is_corrector', '=', False)]}" confirm="This will approve the proposition text."/>
<button type="object" name="submit_correction" string="Submit corrections" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'submit'),('is_corrector', '=', False)]}"/>
<button type="object" name="validate_correction" string="Validate corrections" class="oe_highlight" attrs="{'invisible': ['|','|', ('state', '!=', 'pending'),('is_proposer', '=', False),('is_corrected', '=', False)]}" confirm="This will approve the corrections."/>
<button type="object" name="discard_correction" string="Validate my version" attrs="{'invisible': ['|','|', ('state', '!=', 'pending'),('is_proposer', '=', False),('is_corrected', '=', False)]}" confirm="This will discard corrections and approve your version."/>

<!-- Corrections to Approve / New Proposition -->
<button type="object" name="validate_correction" string="Approve corrections" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'corrected'),('is_proposer', '=', False)]}" confirm="This will approve the corrections."/>
<button type="object" name="edit_correction" string="Edit corrections" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'corrected'),('is_proposer', '=', False)]}" confirm="This will discard your original proposition and allow you to edit further the corrected text."/>
<button type="object" name="discard_correction" string="Discard corrections" attrs="{'invisible': ['|', ('state', '!=', 'corrected'),('is_proposer', '=', False)]}" confirm="This will discard corrections and let you start over your proposition."/>

<!-- Cancel Approval -->
<button type="object" name="cancel_approve" string="Cancel approval" attrs="{'invisible': ['|','|', ('state', '!=', 'approved'), '&amp;', ('is_proposer', '=', False),('is_corrector', '=', False)]}"/>
</header>
<sheet>
Expand Down Expand Up @@ -104,8 +120,8 @@
<field name="proposition_text" widget="text_ckeditor4" attrs="{'required': [('state', '=', 'pending')], 'readonly': ['|', ('is_proposer', '=', False), ('state', '!=', 'pending')]}"/>
</group>
<group attrs="{'invisible': [('proposition_correction', '=', False)]}">
<field name="subject_correction" attrs="{'readonly': ['|', ('is_corrector', '=', False),('state','!=','submit')]}" states="pending,submit"/>
<field name="proposition_correction" widget="text_ckeditor4" attrs="{'readonly': ['|', ('is_corrector', '=', False),('state','!=','submit')]}" states="pending,submit"/>
<field name="subject_correction" attrs="{'readonly': ['|', ('is_corrector', '=', False),('state','!=','submit')]}" states="pending,submit,corrected"/>
<field name="proposition_correction" widget="text_ckeditor4" attrs="{'readonly': ['|', ('is_corrector', '=', False),('state','!=','submit')]}" states="pending,submit,corrected"/>
</group>
<group string="Compare with other translations" attrs="{'invisible': ['|', ('state', 'not in', ('pending','submit')),('is_master_version', '=', True)]}">
<field name="compare_lang" attrs="{'invisible': [('is_master_version', '=', True)]}"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<form>
<field name="revision_id" invisible="1"/>
<field name="state" invisible="1"/>
<p>This will submit your text to <b><field name="reviser_name" readonly="1" states="submit"/><field name="corrector_name" readonly="1" states="pending"/></b>. Add comments to explain what you changed if necessary.</p>
<p>This will submit your text to <b><field name="reviser_name" readonly="1" states="submit"/><field name="corrector_name" readonly="1" states="pending,corrected"/></b>. Add comments to explain what you changed if necessary.</p>
<group>
<field name="comments"/>
</group>
Expand Down
Loading

0 comments on commit 6afc458

Please sign in to comment.