Browse Source

Aug 07: [FIX] Bug Fixed 'survey_upload_file'

pull/313/merge
Risvana Cybro 1 month ago
parent
commit
eb6afdadab
  1. 10
      survey_upload_file/doc/RELEASE_NOTES.md
  2. 85
      survey_upload_file/models/survey_user_input.py
  3. 70
      survey_upload_file/static/src/js/survey_form_attachment.js
  4. 2
      survey_upload_file/views/survey_templates.xml

10
survey_upload_file/doc/RELEASE_NOTES.md

@ -1,12 +1,14 @@
## Module <survey_upload_file> ## Module <survey_upload_file>
#### 07.06.2024 #### 07.06.2024
#### Version 16.0.1.0.0 #### Version 17.0.1.0.0
#### ADD #### ADD
- Initial Commit for File Upload In Survey - Initial Commit for File Upload In Survey
#### 23.12.2024 #### 05.08.2025
#### Version 17.0.1.0.1 #### Version 17.0.1.0.1
#### Update #### BUG_FIX
- Updated with the issue in index.
- Fixed the bug when updating multiple files.

85
survey_upload_file/models/survey_user_input.py

@ -19,7 +19,8 @@
# If not, see <http://www.gnu.org/licenses/>. # If not, see <http://www.gnu.org/licenses/>.
# #
############################################################################## ##############################################################################
from odoo import models from odoo import models, _
from odoo.exceptions import UserError
class SurveyUserInput(models.Model): class SurveyUserInput(models.Model):
@ -37,21 +38,9 @@ class SurveyUserInput(models.Model):
""" """
_inherit = "survey.user_input" _inherit = "survey.user_input"
def _save_lines(self, question, answer, comment=None, def _save_line_file_upload(self, question, old_answers, answer):
overwrite_existing=False):
"""Save the user's answer for the given question."""
old_answers = self.env['survey.user_input.line'].search([
('user_input_id', '=', self.id),
('question_id', '=', question.id), ])
if question.question_type in 'upload_file':
res = self._save_line_simple_answer(question, old_answers, answer)
else:
res = super()._save_lines(question, answer, comment,
overwrite_existing)
return res
def _save_line_simple_answer(self, question, old_answers, answer):
""" Save the user's file upload answer for the given question.""" """ Save the user's file upload answer for the given question."""
print('old_answers', old_answers)
vals = self._get_line_answer_file_upload_values(question, vals = self._get_line_answer_file_upload_values(question,
'upload_file', answer) 'upload_file', answer)
if old_answers: if old_answers:
@ -60,27 +49,71 @@ class SurveyUserInput(models.Model):
else: else:
return self.env['survey.user_input.line'].create(vals) return self.env['survey.user_input.line'].create(vals)
def _save_lines(self, question, answer, comment=None,
overwrite_existing=True):
""" Save answers to questions, depending on question type.
:param bool overwrite_existing: if an answer already exists for question and user_input_id
it will be overwritten (or deleted for 'choice' questions) in order to maintain data consistency.
:raises UserError: if line exists and overwrite_existing is False
"""
old_answers = self.env['survey.user_input.line'].search([
('user_input_id', '=', self.id),
('question_id', '=', question.id)
])
if old_answers and not overwrite_existing:
raise UserError(_("This answer cannot be overwritten."))
if question.question_type in ['char_box', 'text_box', 'numerical_box',
'date', 'datetime']:
self._save_line_simple_answer(question, old_answers, answer)
if question.save_as_email and answer:
self.write({'email': answer})
if question.save_as_nickname and answer:
self.write({'nickname': answer})
elif question.question_type in ['simple_choice', 'multiple_choice']:
self._save_line_choice(question, old_answers, answer, comment)
elif question.question_type == 'matrix':
self._save_line_matrix(question, old_answers, answer, comment)
elif question.question_type == 'upload_file':
self._save_line_file_upload(question, old_answers, answer)
else:
raise AttributeError(
question.question_type + ": This type of question has no saving function")
def _get_line_answer_file_upload_values(self, question, answer_type, def _get_line_answer_file_upload_values(self, question, answer_type,
answer): answer):
"""Get the values to use when creating or updating a user input line answer = answer[0]
for a file upload answer."""
vals = { vals = {
'user_input_id': self.id, 'user_input_id': self.id,
'question_id': question.id, 'question_id': question.id,
'skipped': False, 'skipped': False,
'answer_type': answer_type, 'answer_type': answer_type,
'display_name': 'Upload File',
} }
if answer_type == 'upload_file': if answer_type == 'upload_file':
attachment_ids = [] # Parse JSON if needed
if len(answer) >= 2:
file_data = answer[0] attachments = []
file_name = answer[1] for file_info in answer:
for file in range(len(answer[1])): if not isinstance(file_info, dict):
raise UserError("Each uploaded file must be a dictionary.")
file_data = file_info.get('data')
file_name = file_info.get('name')
if file_data and file_name:
attachment = self.env['ir.attachment'].create({ attachment = self.env['ir.attachment'].create({
'name': file_name[file], 'name': file_name,
'type': 'binary', 'type': 'binary',
'datas': file_data[file], 'datas': file_data,
}) })
attachment_ids.append(attachment.id) attachments.append((4, attachment.id))
vals['value_file_data_ids'] = attachment_ids else:
raise UserError("Missing file name or data.")
vals['value_file_data_ids'] = attachments
return vals return vals

70
survey_upload_file/static/src/js/survey_form_attachment.js

@ -12,50 +12,30 @@ publicWidget.registry.SurveyFormUpload = publicWidget.Widget.extend(SurveyPreloa
this._super(...arguments); this._super(...arguments);
this.rpc = this.bindService("rpc"); this.rpc = this.bindService("rpc");
}, },
/** On adding file function */ _onFileChange: function (ev) {
_onFileChange: function(event) { const inputEl = ev.currentTarget;
var self = this; const files = ev.target.files;
var files = event.target.files; if (!files || files.length === 0) return;
var fileNames = [];
var dataURLs = []; const readFile = (file) => {
for (let i = 0; i < files.length; i++) { return new Promise((resolve, reject) => {
var reader = new FileReader(); const reader = new FileReader();
reader.readAsDataURL(files[i]); reader.onload = () => {
reader.onload = function(e) { const base64 = reader.result.split(',')[1];
var file = files[i]; resolve({
var filename = file.name; data: base64,
var dataURL = e.target.result.split(',')[1]; /** split base64 data */ name: file.name
fileNames.push(filename); });
dataURLs.push(dataURL); };
/** Set the data-oe-data and data-oe-file_name attributes of the input element self call el */ reader.onerror = reject;
var $input = self.$el.find('input.o_survey_upload_file'); reader.readAsDataURL(file);
$input.attr('data-oe-data', JSON.stringify(dataURLs)); });
$input.attr('data-oe-file_name', JSON.stringify(fileNames)); };
// Create file list elements
var fileList = document.getElementById('fileList'); Promise.all([...files].map(readFile)).then(results => {
fileList.innerHTML = ''; // clear previous contents of file list inputEl.setAttribute('data-oe-data', JSON.stringify(results));
var ul = document.createElement('ul'); });
fileNames.forEach(function(fileName) { }
var li = document.createElement('li');
li.textContent = fileName;
ul.appendChild(li);
});
// Create delete button
var deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete All';
deleteBtn.addEventListener('click', function() {
// Clear file list
fileList.innerHTML = '';
// Clear input field attributes
$input.attr('data-oe-data', '');
$input.attr('data-oe-file_name', '');
self.$el.find('input[type="file"]').val('');
});
// Append file list and delete button to file input container
fileList.appendChild(ul);
fileList.appendChild(deleteBtn);
}
}
},
}); });
export default publicWidget.registry.SurveyFormUpload; export default publicWidget.registry.SurveyFormUpload;

2
survey_upload_file/views/survey_templates.xml

@ -64,4 +64,4 @@
</div> </div>
</t> </t>
</template> </template>
</odoo> </odoo>
Loading…
Cancel
Save