first push message
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
from . import controllers
|
||||
from . import models
|
||||
from . import wizard
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
'name': "survey_xls_report",
|
||||
|
||||
'summary': "Short (1 phrase/line) summary of the module's purpose",
|
||||
|
||||
'description': """
|
||||
Long description of module's purpose
|
||||
""",
|
||||
|
||||
'author': "My Company",
|
||||
'website': "https://www.yourcompany.com",
|
||||
|
||||
# Categories can be used to filter modules in modules listing
|
||||
# Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml
|
||||
# for the full list
|
||||
'category': 'Uncategorized',
|
||||
'version': '0.1',
|
||||
|
||||
# any module necessary for this one to work correctly
|
||||
'depends': ['base','survey','report_xlsx'],
|
||||
|
||||
# always loaded
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/survey_export_wizard.xml',
|
||||
'report/survey_excel_export.xml',
|
||||
'views/views.xml',
|
||||
'views/templates.xml',
|
||||
],
|
||||
# only loaded in demonstration mode
|
||||
'demo': [
|
||||
'demo/demo.xml',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from . import controllers
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
# from odoo import http
|
||||
|
||||
|
||||
# class SurveyXlsReport(http.Controller):
|
||||
# @http.route('/survey_xls_report/survey_xls_report', auth='public')
|
||||
# def index(self, **kw):
|
||||
# return "Hello, world"
|
||||
|
||||
# @http.route('/survey_xls_report/survey_xls_report/objects', auth='public')
|
||||
# def list(self, **kw):
|
||||
# return http.request.render('survey_xls_report.listing', {
|
||||
# 'root': '/survey_xls_report/survey_xls_report',
|
||||
# 'objects': http.request.env['survey_xls_report.survey_xls_report'].search([]),
|
||||
# })
|
||||
|
||||
# @http.route('/survey_xls_report/survey_xls_report/objects/<model("survey_xls_report.survey_xls_report"):obj>', auth='public')
|
||||
# def object(self, obj, **kw):
|
||||
# return http.request.render('survey_xls_report.object', {
|
||||
# 'object': obj
|
||||
# })
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<!--
|
||||
<record id="object0" model="survey_xls_report.survey_xls_report">
|
||||
<field name="name">Object 0</field>
|
||||
<field name="value">0</field>
|
||||
</record>
|
||||
|
||||
<record id="object1" model="survey_xls_report.survey_xls_report">
|
||||
<field name="name">Object 1</field>
|
||||
<field name="value">10</field>
|
||||
</record>
|
||||
|
||||
<record id="object2" model="survey_xls_report.survey_xls_report">
|
||||
<field name="name">Object 2</field>
|
||||
<field name="value">20</field>
|
||||
</record>
|
||||
|
||||
<record id="object3" model="survey_xls_report.survey_xls_report">
|
||||
<field name="name">Object 3</field>
|
||||
<field name="value">30</field>
|
||||
</record>
|
||||
|
||||
<record id="object4" model="survey_xls_report.survey_xls_report">
|
||||
<field name="name">Object 4</field>
|
||||
<field name="value">40</field>
|
||||
</record>
|
||||
-->
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,160 @@
|
||||
import base64
|
||||
import io
|
||||
import logging
|
||||
from odoo import models, fields
|
||||
from PIL import Image
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SurveyXlsReport(models.AbstractModel):
|
||||
_name = 'report.survey_excel_export.survey_xls'
|
||||
_inherit = 'report.report_xlsx.abstract'
|
||||
|
||||
def generate_xlsx_report(self, workbook, data, wizard):
|
||||
# 1. Determine which questions to export
|
||||
all_questions = wizard.survey_id.question_ids
|
||||
if wizard.type_export == 'session':
|
||||
questions = all_questions.filtered(lambda q: q.page_id.is_page)
|
||||
elif wizard.type_export == 'no_session':
|
||||
questions = all_questions.filtered(lambda q: not q.page_id.is_page)
|
||||
else:
|
||||
questions = all_questions.filtered(lambda q: not q.is_page)
|
||||
|
||||
# 2. Define Headers
|
||||
headers = ['Survey Title', 'Respondent', 'Completion Date', 'Email'] + [q.title for q in questions]
|
||||
sheet = workbook.add_worksheet('Survey Answers')
|
||||
bold = workbook.add_format({'bold': True})
|
||||
|
||||
for col, header in enumerate(headers):
|
||||
sheet.write(0, col, header, bold)
|
||||
|
||||
# 3. Fetch Survey Inputs
|
||||
domain = [('survey_id', '=', wizard.survey_id.id)]
|
||||
if wizard.export_type == 'completed':
|
||||
domain.append(('state', '=', 'done'))
|
||||
if wizard.date_from:
|
||||
domain.append(('create_date', '>=', wizard.date_from))
|
||||
if wizard.date_to:
|
||||
domain.append(('create_date', '<=', wizard.date_to))
|
||||
|
||||
surveys = self.env['survey.user_input'].search(domain)
|
||||
|
||||
# 4. Write Data
|
||||
row = 1
|
||||
if wizard.export_type == 'group_by_partner':
|
||||
partners = surveys.mapped('partner_id') or [False]
|
||||
for partner in partners:
|
||||
partner_name = partner.name if partner else "Undefined Partner"
|
||||
sheet.merge_range(row, 0, row, len(headers) - 1, partner_name, bold)
|
||||
row += 1
|
||||
partner_surveys = surveys.filtered(lambda s: s.partner_id == partner)
|
||||
row = self._write_survey_rows(sheet, partner_surveys, row, headers, questions)
|
||||
else:
|
||||
row = self._write_survey_rows(sheet, surveys, row, headers, questions)
|
||||
|
||||
def _get_answer_value(self, answer_lines, question):
|
||||
"""Retrieve answer value based on Odoo 19 question_type fields."""
|
||||
if not answer_lines:
|
||||
return ""
|
||||
|
||||
try:
|
||||
q_type = question.question_type
|
||||
|
||||
if q_type == 'text_box':
|
||||
return answer_lines.value_text_box or ""
|
||||
elif q_type == 'char_box':
|
||||
return answer_lines.value_char_box or ""
|
||||
elif q_type == 'numerical_box':
|
||||
return str(answer_lines.value_numerical_box) if answer_lines.value_numerical_box is not None else ""
|
||||
elif q_type == 'scale':
|
||||
return str(answer_lines.value_scale) if answer_lines.value_scale else ""
|
||||
elif q_type == 'date':
|
||||
return answer_lines.value_date or ""
|
||||
elif q_type == 'datetime':
|
||||
return answer_lines.value_datetime or ""
|
||||
|
||||
# ✅ FIXED: Handle simple_choice & multiple_choice properly
|
||||
elif question.question_type in ['simple_choice', 'multiple_choice']:
|
||||
# Join values from suggested answers
|
||||
return ", ".join(answer_lines.suggested_answer_id.mapped('value')) if answer_lines.suggested_answer_id else ""
|
||||
# answer_lines may contain 1 record (simple) or N records (multiple)
|
||||
# .mapped() safely extracts the value from all records
|
||||
selected_values = answer_lines.mapped('value_suggested.value')
|
||||
return ", ".join(filter(None, selected_values))
|
||||
|
||||
# ✅ FIXED: Handle matrix answers properly
|
||||
elif q_type == 'matrix':
|
||||
parts = []
|
||||
for line in answer_lines:
|
||||
row_val = line.matrix_row_id.value if line.matrix_row_id else ""
|
||||
col_val = line.value_suggested.value if line.value_suggested else ""
|
||||
if row_val and col_val:
|
||||
parts.append(f"{row_val}: {col_val}")
|
||||
return ", ".join(parts)
|
||||
|
||||
else:
|
||||
return ""
|
||||
|
||||
except Exception as e:
|
||||
_logger.error(f"Error getting answer for '{question.title}': {e}")
|
||||
return ""
|
||||
|
||||
def _write_survey_rows(self, sheet, surveys, row, headers, questions):
|
||||
DEFAULT_ROW_HEIGHT = 100
|
||||
DEFAULT_COLUMN_WIDTH = 20
|
||||
POINTS_TO_PIXELS = 1.33
|
||||
CHARACTERS_TO_PIXELS = 7
|
||||
|
||||
for survey_input in surveys:
|
||||
# Write Metadata
|
||||
sheet.write(row, 0, survey_input.survey_id.title)
|
||||
sheet.write(row, 1, survey_input.partner_id.name or survey_input.display_name)
|
||||
sheet.write(row, 2,
|
||||
survey_input.create_date.strftime('%Y-%m-%d %H:%M:%S') if survey_input.create_date else "")
|
||||
sheet.write(row, 3, survey_input.email or "")
|
||||
|
||||
# Write Answers
|
||||
for col_offset, question in enumerate(questions, start=4):
|
||||
answer_line = survey_input.user_input_line_ids.filtered(
|
||||
lambda l: l.question_id == question
|
||||
)
|
||||
value = self._get_answer_value(answer_line, question)
|
||||
|
||||
# Handle custom file/image question type safely
|
||||
if question.question_type == 'que_sh_file' and value:
|
||||
try:
|
||||
# Decode base64 image data
|
||||
image_bytes = base64.b64decode(value)
|
||||
image_stream = io.BytesIO(image_bytes)
|
||||
img = Image.open(image_stream)
|
||||
|
||||
# Resize to fit cell
|
||||
MAX_W, MAX_H = 150, 100
|
||||
img.thumbnail((MAX_W, MAX_H), Image.Resampling.LANCZOS)
|
||||
|
||||
resized_stream = io.BytesIO()
|
||||
img.save(resized_stream, format='PNG')
|
||||
resized_stream.seek(0)
|
||||
|
||||
w_px, h_px = img.size
|
||||
cell_w_px = DEFAULT_COLUMN_WIDTH * CHARACTERS_TO_PIXELS
|
||||
cell_h_px = DEFAULT_ROW_HEIGHT * POINTS_TO_PIXELS
|
||||
|
||||
x_offset = max(0, (cell_w_px - w_px) / 2)
|
||||
y_offset = max(0, (cell_h_px - h_px) / 2)
|
||||
|
||||
sheet.set_row(row, DEFAULT_ROW_HEIGHT)
|
||||
sheet.set_column(col_offset, col_offset, DEFAULT_COLUMN_WIDTH)
|
||||
|
||||
sheet.insert_image(
|
||||
row, col_offset, "temp_image.png",
|
||||
{'image_data': resized_stream, 'x_offset': x_offset, 'y_offset': y_offset}
|
||||
)
|
||||
except Exception as e:
|
||||
sheet.write(row, col_offset, f"Image Error: {str(e)}")
|
||||
else:
|
||||
sheet.write(row, col_offset, value or '')
|
||||
|
||||
row += 1
|
||||
return row
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="action_survey_xls_report" model="ir.actions.report">
|
||||
<field name="name">survey_excel_export</field>
|
||||
<field name="model">survey.export.wizard</field>
|
||||
<field name="report_type">xlsx</field>
|
||||
<field name="report_name">survey_excel_export.survey_xls</field>
|
||||
<field name="report_file">survey_excel_export</field>
|
||||
<field name="print_report_name">'Survey_Report_list'</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,2 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_survey_export_wizard,survey wizard,model_survey_export_wizard,base.group_user,1,1,1,0
|
||||
|
@@ -0,0 +1,24 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<!--
|
||||
<template id="listing">
|
||||
<ul>
|
||||
<li t-foreach="objects" t-as="object">
|
||||
<a t-attf-href="#{ root }/objects/#{ object.id }">
|
||||
<t t-esc="object.display_name"/>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<template id="object">
|
||||
<h1><t t-esc="object.display_name"/></h1>
|
||||
<dl>
|
||||
<t t-foreach="object._fields" t-as="field">
|
||||
<dt><t t-esc="field"/></dt>
|
||||
<dd><t t-esc="object[field]"/></dd>
|
||||
</t>
|
||||
</dl>
|
||||
</template>
|
||||
-->
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,17 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_survey_form_inherit" model="ir.ui.view">
|
||||
<field name="name">survey inherit</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="inherit_id" ref="survey.survey_survey_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_archive']" position="after">
|
||||
<button string="Open Wizard"
|
||||
type="action"
|
||||
name="%(action_open_survey_wizard)d"
|
||||
class="btn-primary"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import wizard
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="view_survey_export_wizard" model="ir.ui.view">
|
||||
<field name="name">survey.export.wizard.form</field>
|
||||
<field name="model">survey.export.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Export Survey to Excel">
|
||||
<group>
|
||||
<field name="survey_id"/>
|
||||
<field name="export_type"/>
|
||||
<field name="type_export"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="status" invisible="1"/>
|
||||
</group>
|
||||
<group string="Processing Results" invisible="status not in ('processing', 'done')" colspan="4">
|
||||
<group>
|
||||
<field name="processed_count" readonly="1"/>
|
||||
<field name="updated_records" readonly="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="no_match_count" readonly="1"/>
|
||||
<field name="error_count" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<!-- Processing Details - shown when status is done -->
|
||||
<group string="Details" invisible="status != 'done'" colspan="4">
|
||||
<field name="details" readonly="1" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
|
||||
<footer>
|
||||
<!-- Buttons for draft state -->
|
||||
<button string="Export to Excel" type="object" name="export_to_excel" class="btn-primary" invisible="status != 'draft'"/>
|
||||
<button string="Process & Export" type="object" name="process_and_export" class="btn-secondary" invisible="status != 'draft'"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" invisible="status != 'draft'"/>
|
||||
|
||||
<!-- Buttons for processing state -->
|
||||
<button string="Processing..." class="btn-primary" disabled="1" invisible="status != 'processing'"/>
|
||||
|
||||
<!-- Buttons for done state -->
|
||||
<button string="Export to Excel" type="object" name="export_to_excel" class="btn-primary" invisible="status != 'done'"/>
|
||||
<button string="Process Another" type="object" name="reset_wizard" class="btn-secondary" invisible="status != 'done'"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" invisible="status != 'done'"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_open_survey_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Survey Action Wizard</field>
|
||||
<field name="res_model">survey.export.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_survey_id': active_id}</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,273 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api
|
||||
from datetime import datetime
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
class SurveyExportWizard(models.TransientModel):
|
||||
_name = "survey.export.wizard"
|
||||
_description = "Survey Export Wizard"
|
||||
|
||||
survey_id = fields.Many2one('survey.survey', string='Survey', required=True)
|
||||
date_from = fields.Datetime(string='From Date')
|
||||
date_to = fields.Datetime(string='To Date')
|
||||
export_type = fields.Selection([
|
||||
('completed', 'Only Completed Surveys'),
|
||||
('group_by_partner', 'Group By Partner')
|
||||
], string='Export Type', default='completed', required=True)
|
||||
type_export = fields.Selection([('session','session'),('no_session','no session')], string='Export')
|
||||
def export_to_excel(self):
|
||||
return self.env.ref('survey_xls_report.action_survey_xls_report').report_action(self)
|
||||
|
||||
processed_count = fields.Integer('Processed Surveys', readonly=True)
|
||||
updated_records = fields.Integer('Updated Records', readonly=True)
|
||||
no_match_count = fields.Integer('No Matches', readonly=True)
|
||||
error_count = fields.Integer('Errors', readonly=True)
|
||||
status = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('processing', 'Processing'),
|
||||
('done', 'Completed')
|
||||
], default='draft', readonly=True)
|
||||
details = fields.Text('Processing Details', readonly=True)
|
||||
|
||||
def process_and_export(self):
|
||||
self.ensure_one()
|
||||
|
||||
# Update status to processing
|
||||
self.write({'status': 'processing'})
|
||||
|
||||
# Build domain for survey inputs - ONLY COMPLETED SURVEYS
|
||||
domain = [
|
||||
('survey_id', '=', self.survey_id.id),
|
||||
('state', '=', 'done') # Only completed surveys
|
||||
]
|
||||
if self.date_from:
|
||||
domain.append(('create_date', '>=', self.date_from))
|
||||
if self.date_to:
|
||||
domain.append(('create_date', '<=', self.date_to))
|
||||
|
||||
# Get only completed survey inputs
|
||||
survey_inputs = self.env['survey.user_input'].search(domain)
|
||||
|
||||
processed_count = 0
|
||||
updated_records = 0
|
||||
no_match_count = 0
|
||||
error_count = 0
|
||||
details = []
|
||||
|
||||
# Process each completed survey input
|
||||
for user_input in survey_inputs:
|
||||
try:
|
||||
name, dob = self._extract_survey_data(user_input)
|
||||
|
||||
if name and dob:
|
||||
updated_count_local = self._update_info_model_status(name, dob, user_input)
|
||||
|
||||
if updated_count_local > 0:
|
||||
updated_records += updated_count_local
|
||||
details.append(f"✓ Survey {user_input.id}: Updated {updated_count_local} record(s) for {name}")
|
||||
else:
|
||||
no_match_count += 1
|
||||
details.append(f"○ Survey {user_input.id}: No match found for {name}")
|
||||
|
||||
processed_count += 1
|
||||
else:
|
||||
if not name and not dob:
|
||||
details.append(f"○ Survey {user_input.id}: Missing both name and DOB data")
|
||||
elif not name:
|
||||
details.append(f"○ Survey {user_input.id}: Missing name data")
|
||||
no_match_count += 1
|
||||
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
details.append(f"✗ Survey {user_input.id}: Error - {str(e)}")
|
||||
|
||||
# Prepare results
|
||||
summary = [
|
||||
f"Processing Summary for Survey: {self.survey_id.title}",
|
||||
f"=================================================",
|
||||
f"Total Completed Surveys Processed: {processed_count}",
|
||||
f"Records Updated: {updated_records}",
|
||||
f"No Matches: {no_match_count}",
|
||||
f"Errors: {error_count}",
|
||||
"",
|
||||
"Details:",
|
||||
"========"
|
||||
]
|
||||
|
||||
summary.extend(details)
|
||||
|
||||
# Update wizard results
|
||||
self.write({
|
||||
'processed_count': processed_count,
|
||||
'updated_records': updated_records,
|
||||
'no_match_count': no_match_count,
|
||||
'error_count': error_count,
|
||||
'details': '\n'.join(summary),
|
||||
'status': 'done'
|
||||
})
|
||||
|
||||
# Now export to Excel
|
||||
return self.export_to_excel()
|
||||
|
||||
def _extract_survey_data(self, user_input):
|
||||
"""
|
||||
Extract name and date of birth from completed survey answers
|
||||
"""
|
||||
name = None
|
||||
dob = None
|
||||
|
||||
# Debug: Print all questions and their types
|
||||
print("=== ALL SURVEY QUESTIONS ===")
|
||||
for line in user_input.user_input_line_ids:
|
||||
print(
|
||||
f"Question: '{line.question_id.title}' | Type: {line.question_id.question_type} | Value: {self._get_debug_value(line)}")
|
||||
|
||||
# Common keywords for name and DOB questions
|
||||
name_keywords = [
|
||||
'គោត្ដនាម និងនាម៖', 'name', 'full name', 'employee name', 'participant name', 'ឈ្មោះ'
|
||||
]
|
||||
dob_keywords = [
|
||||
'ថ្ថ្ងៃ ខែ ឆ្នាំកំណើត៖', 'date of birth', 'birthday', 'dob', 'birth', 'ថ្ងៃខែឆ្នាំកំណើត'
|
||||
]
|
||||
|
||||
for line in user_input.user_input_line_ids:
|
||||
question_title = line.question_id.title.strip() # Don't convert to lower for Khmer text
|
||||
question_title_lower = question_title.lower()
|
||||
|
||||
# Extract name
|
||||
if any(keyword in question_title or keyword in question_title_lower for keyword in name_keywords):
|
||||
print("Found NAME question")
|
||||
# Handle different question types for name
|
||||
if hasattr(line, 'value_char_box') and line.value_char_box:
|
||||
name = line.value_char_box.strip()
|
||||
print(f"Name from char_box: '{name}'")
|
||||
elif hasattr(line, 'value_text_box') and line.value_text_box:
|
||||
name = line.value_text_box.strip()
|
||||
print(f"Name from text_box: '{name}'")
|
||||
elif hasattr(line, 'suggested_answer_id') and line.suggested_answer_id:
|
||||
name = line.suggested_answer_id.value.strip()
|
||||
print(f"Name from suggested_answer: '{name}'")
|
||||
|
||||
# Extract date of birth
|
||||
elif any(keyword in question_title or keyword in question_title_lower for keyword in dob_keywords):
|
||||
print("Found DOB question")
|
||||
print(f"Question type: {line.question_id.question_type}")
|
||||
|
||||
# Handle different question types for date
|
||||
if hasattr(line, 'value_date') and line.value_date:
|
||||
dob = line.value_date
|
||||
print(f"DOB from value_date: {dob}")
|
||||
elif hasattr(line, 'value_datetime') and line.value_datetime:
|
||||
# If datetime, extract just the date part
|
||||
if isinstance(line.value_datetime, datetime):
|
||||
dob = line.value_datetime.date()
|
||||
print(f"DOB from datetime: {dob}")
|
||||
else:
|
||||
dob = line.value_datetime
|
||||
print(f"DOB from value_datetime: {dob}")
|
||||
elif hasattr(line, 'value_char_box') and line.value_char_box:
|
||||
# Try to parse date from char box
|
||||
date_str = line.value_char_box.strip()
|
||||
print(f"DOB from char_box (string): '{date_str}'")
|
||||
# You might need to parse this string to a date object
|
||||
# Example: if date_str is in format '2023-12-25'
|
||||
try:
|
||||
from datetime import datetime
|
||||
dob = datetime.strptime(date_str, '%d/%m/%Y').date()
|
||||
print(f"Parsed DOB: {dob}")
|
||||
except:
|
||||
print("Could not parse date string")
|
||||
elif hasattr(line, 'value_text_box') and line.value_text_box:
|
||||
# Try to parse date from text box
|
||||
date_str = line.value_text_box.strip()
|
||||
print(f"DOB from text_box (string): '{date_str}'")
|
||||
try:
|
||||
from datetime import datetime
|
||||
dob = datetime.strptime(date_str, '%d/%m/%Y').date()
|
||||
print(f"Parsed DOB: {dob}")
|
||||
except:
|
||||
print("Could not parse date string")
|
||||
print("=================",name ,"===dob",dob)
|
||||
return name, dob
|
||||
|
||||
def _get_debug_value(self, line):
|
||||
"""Helper method to get the value from a survey line for debugging"""
|
||||
if hasattr(line, 'value_char_box') and line.value_char_box:
|
||||
return f"char_box: '{line.value_char_box}'"
|
||||
elif hasattr(line, 'value_text_box') and line.value_text_box:
|
||||
return f"text_box: '{line.value_text_box}'"
|
||||
elif hasattr(line, 'value_date') and line.value_date:
|
||||
return f"date: {line.value_date}"
|
||||
elif hasattr(line, 'value_datetime') and line.value_datetime:
|
||||
return f"datetime: {line.value_datetime}"
|
||||
elif hasattr(line, 'value_numerical_box') and line.value_numerical_box is not None:
|
||||
return f"numerical: {line.value_numerical_box}"
|
||||
elif hasattr(line, 'suggested_answer_id') and line.suggested_answer_id:
|
||||
return f"suggested: '{line.suggested_answer_id.value}'"
|
||||
else:
|
||||
return "no_value"
|
||||
|
||||
def _update_info_model_status(self, name, dob, survey_input):
|
||||
"""
|
||||
Update status in info model when name and DOB match
|
||||
"""
|
||||
if not name or not dob:
|
||||
print(f"Skipping update - Missing data: name='{name}', dob='{dob}'")
|
||||
return 0
|
||||
|
||||
try:
|
||||
# Debug: Print search criteria
|
||||
print(f"Searching for name: '{name}', dob: {dob}")
|
||||
|
||||
# Search for matching records in your info model
|
||||
info_records = self.env['info.info'].search([
|
||||
('name', '=ilike', name), # Case-insensitive match for name
|
||||
('dob', '=', '08/02/2000') # Exact date match for DOB
|
||||
])
|
||||
|
||||
# Debug: Print search results
|
||||
print(f"Found {len(info_records)} matching records")
|
||||
|
||||
# Debug: Print found records
|
||||
for record in info_records:
|
||||
print(f"Found record - ID: {record.id}, Name: '{record.name}', DOB: {record.date_of_birth}")
|
||||
|
||||
if info_records:
|
||||
# Update status to True and add tracking information
|
||||
info_records.write({
|
||||
'status': True,
|
||||
'survey_processed': True,
|
||||
'survey_id': self.survey_id.id,
|
||||
'survey_input_id': survey_input.id,
|
||||
'processed_date': fields.Datetime.now()
|
||||
})
|
||||
|
||||
_logger.info(f"Updated {len(info_records)} records for {name} with DOB {dob}")
|
||||
return len(info_records)
|
||||
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
_logger.error(f"Database error while updating info model for {name}: {str(e)}")
|
||||
raise Exception(f"Database error while updating: {str(e)}")
|
||||
|
||||
def reset_wizard(self):
|
||||
"""
|
||||
Reset wizard to initial state
|
||||
"""
|
||||
self.write({
|
||||
'processed_count': 0,
|
||||
'updated_records': 0,
|
||||
'no_match_count': 0,
|
||||
'error_count': 0,
|
||||
'status': 'draft',
|
||||
'details': False
|
||||
})
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'survey.export.wizard',
|
||||
'res_id': self.id,
|
||||
'view_mode': 'form',
|
||||
'target': 'new'
|
||||
}
|
||||
Reference in New Issue
Block a user