From 1bd6d2dbae69bf5f0b5e4f942cdc4cc8a06eaf27 Mon Sep 17 00:00:00 2001 From: Eyuael Bezabeh <98238151+EyuaelB@users.noreply.github.com> Date: Tue, 14 Jan 2025 02:45:13 +0300 Subject: [PATCH 1/3] draft publish module --- g2p_draft_publish/README.md | 1 + g2p_draft_publish/__init__.py | 2 + g2p_draft_publish/__manifest__.py | 36 ++ g2p_draft_publish/data/enrichment_status.xml | 10 + g2p_draft_publish/models/__init__.py | 4 + g2p_draft_publish/models/configurations.py | 9 + .../models/draft_import_records.py | 307 +++++++++++++++++ .../models/imported_farmer_records.py | 114 +++++++ .../security/ir.model.access.csv | 20 ++ g2p_draft_publish/security/rules.xml | 54 +++ g2p_draft_publish/static/description/icon.png | Bin 0 -> 3985 bytes g2p_draft_publish/static/src/css/style.css | 4 + g2p_draft_publish/views/configurations.xml | 40 +++ .../views/draft_imported_records.xml | 202 +++++++++++ g2p_draft_publish/views/imported_records.xml | 161 +++++++++ g2p_draft_publish/views/views.xml | 323 ++++++++++++++++++ g2p_draft_publish/wizards/__init__.py | 3 + g2p_draft_publish/wizards/add_followers.py | 55 +++ g2p_draft_publish/wizards/add_followers.xml | 43 +++ g2p_draft_publish/wizards/rejection.py | 56 +++ g2p_draft_publish/wizards/rejection.xml | 48 +++ 21 files changed, 1492 insertions(+) create mode 100644 g2p_draft_publish/README.md create mode 100644 g2p_draft_publish/__init__.py create mode 100644 g2p_draft_publish/__manifest__.py create mode 100644 g2p_draft_publish/data/enrichment_status.xml create mode 100644 g2p_draft_publish/models/__init__.py create mode 100644 g2p_draft_publish/models/configurations.py create mode 100644 g2p_draft_publish/models/draft_import_records.py create mode 100644 g2p_draft_publish/models/imported_farmer_records.py create mode 100644 g2p_draft_publish/security/ir.model.access.csv create mode 100644 g2p_draft_publish/security/rules.xml create mode 100644 g2p_draft_publish/static/description/icon.png create mode 100644 g2p_draft_publish/static/src/css/style.css create mode 100644 g2p_draft_publish/views/configurations.xml create mode 100644 g2p_draft_publish/views/draft_imported_records.xml create mode 100644 g2p_draft_publish/views/imported_records.xml create mode 100644 g2p_draft_publish/views/views.xml create mode 100644 g2p_draft_publish/wizards/__init__.py create mode 100644 g2p_draft_publish/wizards/add_followers.py create mode 100644 g2p_draft_publish/wizards/add_followers.xml create mode 100644 g2p_draft_publish/wizards/rejection.py create mode 100644 g2p_draft_publish/wizards/rejection.xml diff --git a/g2p_draft_publish/README.md b/g2p_draft_publish/README.md new file mode 100644 index 0000000..0b283ac --- /dev/null +++ b/g2p_draft_publish/README.md @@ -0,0 +1 @@ +# g2p_ati_integrations \ No newline at end of file diff --git a/g2p_draft_publish/__init__.py b/g2p_draft_publish/__init__.py new file mode 100644 index 0000000..6ed2c21 --- /dev/null +++ b/g2p_draft_publish/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards \ No newline at end of file diff --git a/g2p_draft_publish/__manifest__.py b/g2p_draft_publish/__manifest__.py new file mode 100644 index 0000000..93b1498 --- /dev/null +++ b/g2p_draft_publish/__manifest__.py @@ -0,0 +1,36 @@ +{ + "name": "Draft Publish Module", + "version": "17.0.0.2", + "summary": "Draft Publish Module", + "category": "tools", + "description": """ +""", + "depends": ["base", 'mail','g2p_social_registry', 'g2p_registry_addl_info', 'web'], + "data": [ + "security/rules.xml", + "security/ir.model.access.csv", + "data/enrichment_status.xml", + "views/configurations.xml", + "views/draft_imported_records.xml", + "views/imported_records.xml", + "wizards/add_followers.xml", + "wizards/rejection.xml" + + ], + + "assets": { + "web.assets_backend": [ + "g2p_draft_publish/static/src/**/*.js", + "g2p_draft_publish/static/src/**/*.css", + "g2p_draft_publish/static/src/**/*.scss", + "g2p_draft_publish/static/src/**/*.xml", + ], + }, + "author": "", + 'website': "", + "installable": True, + "application": False, + "auto_install": False, + # "images": ["static/description/Banner.gif"], + "license":'', +} \ No newline at end of file diff --git a/g2p_draft_publish/data/enrichment_status.xml b/g2p_draft_publish/data/enrichment_status.xml new file mode 100644 index 0000000..f1f2f39 --- /dev/null +++ b/g2p_draft_publish/data/enrichment_status.xml @@ -0,0 +1,10 @@ + + + + + Started + + + + + diff --git a/g2p_draft_publish/models/__init__.py b/g2p_draft_publish/models/__init__.py new file mode 100644 index 0000000..3c46e5f --- /dev/null +++ b/g2p_draft_publish/models/__init__.py @@ -0,0 +1,4 @@ +# from . import res_partner +from . import imported_farmer_records +from . import configurations +from . import draft_import_records \ No newline at end of file diff --git a/g2p_draft_publish/models/configurations.py b/g2p_draft_publish/models/configurations.py new file mode 100644 index 0000000..de6f5e3 --- /dev/null +++ b/g2p_draft_publish/models/configurations.py @@ -0,0 +1,9 @@ +from odoo import models, fields, api, _ + + +class G2PValidationStatus(models.Model): + _name = 'g2p.validation.status' + + name = fields.Char() + + diff --git a/g2p_draft_publish/models/draft_import_records.py b/g2p_draft_publish/models/draft_import_records.py new file mode 100644 index 0000000..9df8d0f --- /dev/null +++ b/g2p_draft_publish/models/draft_import_records.py @@ -0,0 +1,307 @@ +from odoo import models, fields, api +import json +from odoo.exceptions import UserError, ValidationError +from datetime import date, datetime +import logging +from typing import Dict, List +_logger = logging.getLogger(__name__) + + +class BaseInherit(models.AbstractModel): + _inherit = 'base' + + def web_save(self, vals, specification: Dict[str, Dict], next_id=None) -> List[Dict]: + if self._name == 'res.partner' and self.env.context.get('in_enrichment'): + self.action_save_to_draft(vals) + return self + + + if self: + self.write(vals) + else: + self = self.create(vals) + if next_id: + self = self.browse(next_id) + return self.with_context(bin_size=True).web_read(specification) + + +class G2PDraftImportedRecord(models.Model): + _name = "draft.imported.record" + _description = "Draft Imported Records" + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string='Name') + given_name = fields.Char(string="First Name") + family_name = fields.Char(string="Father's Name") + addl_name = fields.Char(string="Grand Father's Name") + phone = fields.Char(string="Phone") + gender = fields.Char() + region = fields.Char(string="Region") + + partner_data = fields.Json(string='Partner Data (JSON)') + validation_status = fields.Many2one('g2p.validation.status') + state = fields.Selection(string='State', selection=[('in_enrichment', 'Enrichment'), ('submitted', 'Submitted'), ('published', 'Published')], default="in_enrichment") + import_record_id = fields.Many2one('g2p.imported.record',string='Import Record') + rejection_reason = fields.Text() + + + def action_publish(self): + self.ensure_one() + partner_data = json.loads(self.partner_data) + res_partner_model = self.env['res.partner'] + + # Fetch all fields metadata from res.partner + fields_metadata = res_partner_model.fields_get() + + # Dictionary to store valid fields and values + valid_data = {} + + given_name = partner_data.get('given_name', '') + family_name = partner_data.get('family_name', '') + gf_name_en = partner_data.get('addl_name', '') + + for field_name, value in partner_data.items(): + if field_name in fields_metadata: + field_info = fields_metadata[field_name] + field_type = field_info.get('type') + + # Validation based on field type + if field_type == 'char' and isinstance(value, str): + valid_data[field_name] = value + elif field_type == 'integer' and isinstance(value, int): + valid_data[field_name] = value + elif field_type == 'float' and isinstance(value, (int, float)): + valid_data[field_name] = float(value) + elif field_type == 'boolean' and isinstance(value, bool): + valid_data[field_name] = value + elif field_type == 'many2one' and isinstance(value, int): + # Check if the referenced record exists + if self.env[field_info['relation']].browse(value).exists(): + valid_data[field_name] = value + elif field_type == 'selection': + selection_options = [option[0] for option in field_info.get('selection', [])] + if value in selection_options: + valid_data[field_name] = value + + # Create the res.partner record with valid data + if valid_data: + valid_data['db_import'] = 'yes' + valid_data['name'] = f"{given_name} {family_name} {gf_name_en}".upper() + + new_partner = res_partner_model.create(valid_data) + self.write({'state':'published'}) + else: + raise ValueError("No valid data found to create a partner record.") + + + def action_submit(self): + self.write({'state':'submitted'}) + + + def action_open_wizard(self): + + self.ensure_one() + active_id = self.id + + if not self.partner_data: + raise UserError("No partner data available to edit.") + try: + json_data = json.loads(self.partner_data) + + except json.JSONDecodeError: + raise UserError("Invalid JSON data in partner_data.") + + partner_model_fields = self.env['res.partner']._fields + _logger.info("the set of fields") + _logger.info(self.env['res.partner']._fields) + _logger.info("the set of the json") + _logger.info(json_data.items()) + additional_g2p_info = {} + context_data = {} + + # excluded = ["land_information_ids", "crop_information_ids", "livestock_information_ids", "phone_number_ids", "reg_ids"] + + for field_name, field_value in json_data.items(): + + if field_name not in partner_model_fields: + additional_g2p_info[field_name] = field_value + continue + + + field = partner_model_fields[field_name] + + if field.type == 'datetime' and isinstance(field_value, str): + _logger.info(f"the datetime field {field_name}") + try: + field_value = datetime.fromisoformat(field_value) + context_data[f"default_{field_name}"] = field_value + except ValueError: + pass + + elif field.type == 'date' and isinstance(field_value, str): + try: + field_value = date.fromisoformat(field_value) + context_data[f"default_{field_name}"] = field_value + except ValueError: + pass # If it's not a valid date string, leave it as is + + elif field.type == 'many2one': + # _logger.info(f"the many2one field 01 {field_name}") + try: + field_value = int(field_value) + if isinstance(field_value, int): + context_data[f"default_{field_name}"] = json_data[field_name] + _logger.info(f"the many2one field {field_name}") + except ValueError as e: + if not isinstance(field_value, int): + additional_g2p_info[field_name] = field_value + + elif field.type == 'many2many': + # _logger.info(f"the field {field_name}") + if isinstance(field_value, list): + if all(isinstance(val, int) for val in field_value): + # If field_value is a list of IDs (int), update the many2many field + context_data[f"default_{field_name}"] = [(6, 0, field_value)] + elif all(hasattr(val, 'id') for val in field_value): + # If field_value is a list of records, extract their IDs + context_data[f"default_{field_name}"] = [(6, 0, [val.id for val in field_value])] + else: + additional_g2p_info[field_name] = field_value + elif hasattr(field_value, 'id'): # If field_value is a single record + # If field_value is a single record, update it as a list with one record + context_data[f"default_{field_name}"] = [(6, 0, [field_value.id])] + else: + additional_g2p_info[field_name] = field_value + + + elif field.type == 'selection': + _logger.info(f"the field {field_name}") + selection_values = field.get_values(env=self.env) + if field_value in selection_values: + context_data[f"default_{field_name}"] = field_value + if field_value not in selection_values: + additional_g2p_info[field_name] = field_value + + else: + context_data[f"default_{field_name}"] = field_value + + context_data['active_id'] = active_id + + return { + 'type': 'ir.actions.act_window', + 'name': 'Record Data', + 'view_mode': 'form', + 'res_model': 'res.partner', + 'view_id': self.env.ref('g2p_draft_publish.g2p_validation_form_view').id, + 'target': 'new', + # 'target': 'current', + 'context': {**context_data, 'default_additional_g2p_info': json.dumps(additional_g2p_info), + 'in_enrichment' : 'yes', + 'default_phone_number_ids': json_data.get('phone_number_ids', []), + 'default_individual_membership_ids': json_data.get('individual_membership_ids', []), + 'default_reg_ids': json_data.get('reg_ids', []) + }, + } + + + + def action_reject(self): + return { + 'name': 'Confirm Rejection', + 'type': 'ir.actions.act_window', + 'res_model': 'reject.wizard', + 'view_mode': 'form', + 'target': 'new', + } + + +class G2PRespartnerIntegration(models.Model): + _inherit = 'res.partner' + + db_import = fields.Selection(string="Imported", index=True, selection=[("yes", "Yes"), ("no", "No")],default="no") + + def action_update(self): + return + + + def action_save_to_draft(self,vals): + + context = self.env.context + model_name = context.get('active_model') + record_id = context.get('active_id') + active_record = self.env[model_name].browse(record_id) + partner_data = json.loads(active_record.partner_data) or {} + + + m2m_fields = { + 'tags_ids': 'tags_ids', + } + + processed_m2m_fields = {} + for field, key in m2m_fields.items(): + processed_m2m_fields[field] = [item[1] for item in vals.get(field, [])] + + + dynamic_fields = { + 'is_company': False, + 'is_group': False, + 'is_registrant': True, + 'db_import': 'yes', + **processed_m2m_fields + + } + + static_fields = [ + 'given_name', 'family_name', 'address', 'addl_name', 'birthdate','region', + 'email', 'gender', 'civil_status', 'district','occupation', 'birthdate_not_exact', 'income','brith_place' + 'martial_status', 'education', + 'is_disabled', 'phone_number_ids','related_1_ids', 'related_2_ids', 'individual_membership_ids','group_memebership_ids', 'reg_ids', + 'additional_g2p_info' + ] + + + draft_record = {} + + draft_record.update(dynamic_fields) + + for field in static_fields: + if field in self.env[model_name]._fields: + draft_record[field] = vals.get(field) or partner_data.get(field) + else: + if vals.get(field): + draft_record[field] = vals[field] + + if vals.get('given_name') or vals.get('family_name') or vals.get('addl_name'): + draft_record['name'] = f"{vals.get('given_name', '').upper()} {vals.get('family_name', '').upper()} {vals.get('addl_name', '').upper()}".strip() + + + active_record.write({ + 'partner_data': json.dumps(draft_record) + }) + + + + + def action_publish(self): + context = self.env.context + model_name = context.get('active_model') + record_id = context.get('active_id') + record = self.env[model_name].browse(record_id) + if record.state=='published': + raise ValidationError("Record already has been published") + else: + record.action_publish() + + + def action_submit(self): + context = self.env.context + model_name = context.get('active_model') + record_id = context.get('active_id') + record = self.env[model_name].browse(record_id) + if record.state=='submitted': + raise ValidationError("Record already has been Submitted") + else: + record.action_submit() + + + diff --git a/g2p_draft_publish/models/imported_farmer_records.py b/g2p_draft_publish/models/imported_farmer_records.py new file mode 100644 index 0000000..0376785 --- /dev/null +++ b/g2p_draft_publish/models/imported_farmer_records.py @@ -0,0 +1,114 @@ +from odoo import models, fields, api +import json +from odoo.exceptions import ValidationError + + +class G2PImportedRecord(models.Model): + _name = 'g2p.imported.record' + _description = 'Imported Record' + _inherit = ['mail.thread', 'mail.activity.mixin'] + + name = fields.Char(string="Name") + given_name = fields.Char(string="First Name") + family_name = fields.Char(string="Father's Name") + gf_name_eng = fields.Char(string="Grand Father's Name") + phone = fields.Char(string="Phone") + gender = fields.Char() + region = fields.Char(string="Region") + state = fields.Selection(string='State', selection=[('draft', 'Draft'), ('moved', 'Created')], default="draft") + language = fields.Char() + record_from = fields.Char() + record_type = fields.Selection(selection=[('single', 'Single Source'),('composed', 'Composed')]) + db_import = fields.Boolean("Imported", default=False) + + + + @api.onchange("family_name", "given_name", "gf_name_eng") + def name_change_farmer(self): + name = "" + if self.given_name: + name += self.given_name + " " + if self.family_name: + name += self.family_name + " " + if self.gf_name_eng: + name += self.gf_name_eng + + self.name = name.upper() + + + def action_view_draft_records(self): + return { + 'name': 'Draft Records', + 'type': 'ir.actions.act_window', + 'res_model': 'draft.imported.record', + 'view_mode': 'kanban,form', + 'domain': [('import_record_id', '=', self.id)], + 'context': dict(self.env.context, default_import_record_id=self.id), + } + + + + def action_to_draft(self): + for record in self: + associated_records = self.env['draft.imported.record'].sudo().search([ + ('import_record_id', '=', record.id) + ]) + + if any(rec.state == 'published' for rec in associated_records): + raise ValidationError( + "Cannot set to draft. There are associated records that are already published." + ) + + associated_records.unlink() + record.write({'state': 'draft'}) + + + + + def action_move(self): + self.write({"state": "moved"}) + + def create_draft_imported_record(self): + self.ensure_one() + + enrichment_started = self.env.ref('g2p_draft_publish.enrichment_started') + + partner_data = { + 'given_name': self.given_name, + 'family_name': self.family_name, + 'addl_name': self.gf_name_eng, + 'phone': self.phone, + 'gender': self.gender, + 'region': self.region + } + + data = { + 'name': self.name, + 'given_name': self.given_name, + 'family_name': self.family_name, + 'addl_name': self.gf_name_eng, + 'phone': self.phone, + 'gender': self.gender, + 'region': self.region, + 'import_record_id': self.id, + 'partner_data' : json.dumps(partner_data), + 'validation_status': enrichment_started.id + + } + + new_record = self.env['draft.imported.record'].sudo().create(data) + new_record.sudo().write({ + 'message_partner_ids': [(6, 0, self.message_partner_ids.ids)] + }) + + self.write({"state": "moved"}) + + return { + 'name': 'Draft Records', + 'type': 'ir.actions.act_window', + 'res_model': 'draft.imported.record', + 'view_mode': 'kanban,form,tree', + 'domain': [('import_record_id', '=', self.id)], + 'context': dict(self.env.context, default_import_record_id=self.id), + } + diff --git a/g2p_draft_publish/security/ir.model.access.csv b/g2p_draft_publish/security/ir.model.access.csv new file mode 100644 index 0000000..aa9585e --- /dev/null +++ b/g2p_draft_publish/security/ir.model.access.csv @@ -0,0 +1,20 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_imported_record_user,access_imported_record_user,model_g2p_imported_record,g2p_draft_publish.group_int_validator,1,1,0,0 +access_imported_record_admin,access_imported_record_admin,model_g2p_imported_record,g2p_draft_publish.group_int_admin,1,1,1,1 +access_draft_imported_record_user,access_draft_imported_record_user,model_draft_imported_record,g2p_draft_publish.group_int_validator,1,1,1,1 +access_g2p_validation_status,status_manager,model_g2p_validation_status,g2p_draft_publish.group_int_admin,1,1,1,1 +access_g2p_validation_status,status_manager_validator,model_g2p_validation_status,g2p_draft_publish.group_int_validator,1,1,1,1 +access_res_partner_val,resp_manager_val,model_res_partner,g2p_draft_publish.group_int_validator,1,1,1,1 +access_reject_wizard,group_reject_wizard_all,model_reject_wizard,g2p_draft_publish.group_int_validator,1,1,1,1 + + + +access_reg_id_group_base_val,g2p_reg_id_group_base_val_access,g2p_registry_base.model_g2p_reg_id,g2p_draft_publish.group_int_validator,1,1,1,1 +access_memebershp_base_val,g2p_memebershp_group_base_val_access,g2p_registry_membership.model_g2p_group_membership,g2p_draft_publish.group_int_validator,1,1,1,1 + +access_reg_rel_group_base_val,g2p_reg_rel_group_base_val_access,g2p_registry_base.model_g2p_reg_rel,g2p_draft_publish.group_int_validator,1,1,1,1 +g2p_phone_number_val,Phone Number val Access,g2p_registry_base.model_g2p_phone_number,g2p_draft_publish.group_int_validator,1,1,1,1 + + + + diff --git a/g2p_draft_publish/security/rules.xml b/g2p_draft_publish/security/rules.xml new file mode 100644 index 0000000..377dd7a --- /dev/null +++ b/g2p_draft_publish/security/rules.xml @@ -0,0 +1,54 @@ + + + + Draft Publish + User access level for Draft Publish module + 3 + + + + + Validator + + + + + Approver + + + + + + Admin + + + + + + Imported Records Follower + + ['|', ('message_partner_ids', 'in', [user.partner_id.id]), ('message_partner_ids','=',False) ] + + + + + Draft Records Follower + + ['|', ('message_partner_ids', 'in', [user.partner_id.id]), ('message_partner_ids','=',False) ] + + + + + Admin Can View ALL Imported Records + + + + + + Admin Can View ALL Draft Imported Records + + + + + + \ No newline at end of file diff --git a/g2p_draft_publish/static/description/icon.png b/g2p_draft_publish/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..5ecb429ea9ceb3863d46ea852dc9c9f78d4e901b GIT binary patch literal 3985 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 literal 0 HcmV?d00001 diff --git a/g2p_draft_publish/static/src/css/style.css b/g2p_draft_publish/static/src/css/style.css new file mode 100644 index 0000000..9bbc042 --- /dev/null +++ b/g2p_draft_publish/static/src/css/style.css @@ -0,0 +1,4 @@ +.btn-close { + display: none !important; +} + diff --git a/g2p_draft_publish/views/configurations.xml b/g2p_draft_publish/views/configurations.xml new file mode 100644 index 0000000..eedc6e4 --- /dev/null +++ b/g2p_draft_publish/views/configurations.xml @@ -0,0 +1,40 @@ + + + + g2p.validation.status.tree + g2p.validation.status + + + + + + + + + + g2p.validation.status.form + g2p.validation.status + +
+ + + +
+
+
+ + + + Enrichment Status + g2p.validation.status + tree + {} + + + + + + + + +
\ No newline at end of file diff --git a/g2p_draft_publish/views/draft_imported_records.xml b/g2p_draft_publish/views/draft_imported_records.xml new file mode 100644 index 0000000..7bb55f9 --- /dev/null +++ b/g2p_draft_publish/views/draft_imported_records.xml @@ -0,0 +1,202 @@ + + + draft.imported.record.tree + draft.imported.record + + + + + + + + + + + + + +