Notes:
diff --git a/contract/security/ir.model.access.csv b/contract/security/ir.model.access.csv
index b596040d3..414522d8a 100644
--- a/contract/security/ir.model.access.csv
+++ b/contract/security/ir.model.access.csv
@@ -9,3 +9,5 @@
"contract_line_portal","Recurring portal","model_contract_line","base.group_portal",1,0,0,0
"contract_template_line_manager","Recurring manager","model_contract_template_line","account.group_account_manager",1,1,1,1
"contract_template_line_user","Recurring user","model_contract_template_line","account.group_account_invoice",1,0,0,0
+"contract_modification_user","Contract modifications - User","model_contract_modification","account.group_account_invoice",1,1,1,1
+"contract_modification_portal","Contract modifications - Portal","model_contract_modification","base.group_portal",1,0,0,0
diff --git a/contract/static/src/scss/frontend.scss b/contract/static/src/scss/frontend.scss
new file mode 100644
index 000000000..3a24a950c
--- /dev/null
+++ b/contract/static/src/scss/frontend.scss
@@ -0,0 +1,71 @@
+/* https://github.com/odoo/odoo/blob/14.0/addons/website/static/src/snippets/s_timeline/000.scss */
+.s_timeline {
+ .s_timeline_line {
+ position: relative;
+ &:before {
+ content: '';
+ position: absolute;
+ width: 1px;
+ top: 0px;
+ bottom: 0px;
+ left: 50%;
+ background-color: gray('800');
+ }
+ }
+ .s_timeline_row {
+ align-items: center;
+ .s_timeline_content {
+ align-items: center;
+ justify-content: flex-end;
+ width: 100%;
+ ~ .s_timeline_content {
+ justify-content: flex-start;
+ }
+ }
+ &.flex-row-reverse {
+ .s_timeline_content {
+ flex-direction: row-reverse;
+ }
+ }
+ @include media-breakpoint-up(md) {
+ &.flex-row-reverse {
+ .s_timeline_content {
+ flex-direction: row-reverse;
+ &:not(:last-child) {
+ margin-left: 10%;
+ }
+ }
+ }
+ &:not(.flex-row-reverse) {
+ .s_timeline_content:last-child {
+ margin-left: 10%;
+ }
+ }
+ }
+ }
+ .s_timeline_date {
+ @include media-breakpoint-up(md) {
+ position: absolute;
+ left: 0%;
+ right: 0%;
+ }
+ @include media-breakpoint-down(sm) {
+ position: relative;
+ margin: 20px 0px;
+ }
+ span:not(.fa) {
+ display: inline-block;
+ padding: 5px;
+ }
+ .fa {
+ margin: 0 $grid-gutter-width/2;
+ }
+ text-align: center;
+ }
+ .s_timeline_icon {
+ flex: 0 0 auto;
+ margin: $grid-gutter-width/2;
+ z-index: 1;
+ }
+}
+
diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py
index 6839a66a4..4481761ae 100644
--- a/contract/tests/test_contract.py
+++ b/contract/tests/test_contract.py
@@ -25,6 +25,7 @@ class TestContractBase(common.SavepointCase):
cls.partner = cls.env['res.partner'].create({
'name': 'partner test contract',
'property_product_pricelist': cls.pricelist.id,
+ 'email': 'demo@demo.com'
})
cls.product_1 = cls.env.ref('product.product_product_1')
cls.product_2 = cls.env.ref('product.product_product_2')
@@ -133,6 +134,42 @@ class TestContract(TestContractBase):
vals.update(overrides)
return self.env['contract.template.line'].create(vals)
+ def test_add_modifications(self):
+ self.contract.message_subscribe(
+ partner_ids=self.contract.partner_id.ids,
+ subtype_ids=self.env.ref(
+ 'contract.mail_message_subtype_contract_modification'
+ ).ids
+ )
+ # Check initial modification auto-creation
+ self.assertEqual(len(self.contract.modification_ids), 1)
+ self.contract.write({
+ 'modification_ids': [
+ (
+ 0,
+ 0,
+ {
+ 'date': '2020-01-01',
+ 'description': 'Modification 1',
+ }
+ ),
+ (
+ 0,
+ 0,
+ {
+ 'date': '2020-02-01',
+ 'description': 'Modification 2',
+ }
+ )
+ ]
+ })
+ self.assertEqual(len(self.contract.message_partner_ids.ids), 2)
+ mail_messages = self.env["mail.message"].search([
+ ("model", "=", "contract.contract"),
+ ("res_id", "=", self.contract.id),
+ ])
+ self.assertGreaterEqual(len(mail_messages), 3)
+
def test_check_discount(self):
with self.assertRaises(ValidationError):
self.acct_line.write({'discount': 120})
diff --git a/contract/views/assets.xml b/contract/views/assets.xml
index d48b516ad..27470c310 100644
--- a/contract/views/assets.xml
+++ b/contract/views/assets.xml
@@ -7,4 +7,9 @@
+
+
+
+
+
diff --git a/contract/views/contract.xml b/contract/views/contract.xml
index 3941f3f07..fe6ab44ac 100644
--- a/contract/views/contract.xml
+++ b/contract/views/contract.xml
@@ -170,6 +170,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/contract/views/contract_portal_templates.xml b/contract/views/contract_portal_templates.xml
index 1792d60e8..33d72da84 100644
--- a/contract/views/contract_portal_templates.xml
+++ b/contract/views/contract_portal_templates.xml
@@ -168,6 +168,29 @@