Skip to content

Commit

Permalink
[IMP] spreadsheet_oca: Allow to import XLSX Files
Browse files Browse the repository at this point in the history
  • Loading branch information
etobella committed Oct 26, 2024
1 parent 9e2d646 commit 13cd33e
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 8 deletions.
2 changes: 2 additions & 0 deletions spreadsheet_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"demo": ["demo/spreadsheet_spreadsheet.xml"],
"assets": {
"web.assets_backend": [
"spreadsheet_oca/static/src/spreadsheet_tree/spreadsheet_tree_view.esm.js",
"spreadsheet_oca/static/src/spreadsheet_tree/spreadsheet_tree_view.xml",
"spreadsheet_oca/static/src/spreadsheet/spreadsheet.scss",
"spreadsheet_oca/static/src/spreadsheet/spreadsheet_action.esm.js",
"spreadsheet_oca/static/src/spreadsheet/pivot_controller.esm.js",
Expand Down
36 changes: 36 additions & 0 deletions spreadsheet_oca/models/spreadsheet_spreadsheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import base64
import json
import zipfile
from io import BytesIO

from odoo import _, api, fields, models

Expand Down Expand Up @@ -55,3 +57,37 @@ def _inverse_spreadsheet_raw(self):
record.data = base64.encodebytes(
json.dumps(record.spreadsheet_raw).encode("UTF-8")
)

def create_document_from_attachment(self, attachment_ids):
attachments = self.env["ir.attachment"].browse(attachment_ids)
spreadsheets = self.env["spreadsheet.spreadsheet"]

Check warning on line 63 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L62-L63

Added lines #L62 - L63 were not covered by tests
for attachment in attachments:
extracted = {}

Check warning on line 65 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L65

Added line #L65 was not covered by tests
with zipfile.ZipFile(
BytesIO(base64.b64decode(attachment.datas)), "r"
) as xlsx:
# List and filter for XML and REL files
xml_files = [
f
for f in xlsx.namelist()
if f.endswith(".xml") or f.endswith(".rels")
]
# Extract each file
for xml_file in xml_files:
# Read the XML file into memory
with xlsx.open(xml_file) as file:
extracted[xml_file] = file.read().decode("UTF8")
spreadsheets |= self.create(

Check warning on line 80 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L79-L80

Added lines #L79 - L80 were not covered by tests
{
"spreadsheet_raw": extracted,
"name": attachment.name,
}
)
attachments.unlink()

Check warning on line 86 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L86

Added line #L86 was not covered by tests
if len(spreadsheets) == 1:
return spreadsheets.get_formview_action()
action = self.env["ir.actions.act_window"]._for_xml_id(

Check warning on line 89 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L88-L89

Added lines #L88 - L89 were not covered by tests
"spreadsheet_oca.spreadsheet_spreadsheet_act_window"
)
action["domain"] = [("id", "in", spreadsheets.ids)]
return action

Check warning on line 93 in spreadsheet_oca/models/spreadsheet_spreadsheet.py

View check run for this annotation

Codecov / codecov/patch

spreadsheet_oca/models/spreadsheet_spreadsheet.py#L92-L93

Added lines #L92 - L93 were not covered by tests
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/** @odoo-module **/

import {makeDynamicCols, makeDynamicRows} from "../utils/dynamic_generators.esm";
import ListDataSource from "@spreadsheet/list/list_data_source";
import PivotDataSource from "@spreadsheet/pivot/pivot_data_source";
import {SpreadsheetControlPanel} from "./spreadsheet_controlpanel.esm";
import {SpreadsheetRenderer} from "./spreadsheet_renderer.esm";
import {registry} from "@web/core/registry";
import spreadsheet from "@spreadsheet/o_spreadsheet/o_spreadsheet_extended";
import {useService} from "@web/core/utils/hooks";
import {makeDynamicCols, makeDynamicRows} from "../utils/dynamic_generators.esm";

const uuidGenerator = new spreadsheet.helpers.UuidGenerator();
const actionRegistry = registry.category("actions");
Expand All @@ -28,13 +28,16 @@ export class ActionSpreadsheetOca extends Component {
});
});
onWillStart(async () => {
// We need to load in case the data comes from an XLSX
this.record =
(await this.orm.call(
this.model,
"get_spreadsheet_data",
[[this.spreadsheetId]],
{context: {bin_size: false}}
)) || {};
spreadsheet.load(
await this.orm.call(
this.model,
"get_spreadsheet_data",
[[this.spreadsheetId]],
{context: {bin_size: false}}
)
) || {};
});
useSubEnv({
saveRecord: this.saveRecord.bind(this),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/** @odoo-module **/
import {Component} from "@odoo/owl";
import {FileUploader} from "@web/views/fields/file_handler";
import {ListController} from "@web/views/list/list_controller";
import {listView} from "@web/views/list/list_view";

import {registry} from "@web/core/registry";
import {standardWidgetProps} from "@web/views/widgets/standard_widget_props";
import {useService} from "@web/core/utils/hooks";

class SpreadsheetFileUploader extends Component {
setup() {
this.orm = useService("orm");
this.attachmentIdsToProcess = [];
this.action = useService("action");
}
async onFileUploaded(file) {
const att_data = {
name: file.name,
mimetype: file.type,
datas: file.data,
};
const att_id = await this.orm.create("ir.attachment", [att_data], {
context: this.env.searchModel.context,
});
this.attachmentIdsToProcess.push(att_id);
}
async onUploadComplete() {
let action = {};
try {
action = await this.orm.call(
"spreadsheet.spreadsheet",
"create_document_from_attachment",
["", this.attachmentIdsToProcess],
{context: this.env.searchModel.context}
);
} finally {
// Ensures attachments are cleared on success as well as on error
this.attachmentIdsToProcess = [];
}
if (action.context && action.context.notifications) {
for (const [file, msg] of Object.entries(action.context.notifications)) {
this.notification.add(msg, {
title: file,
type: "info",
sticky: true,
});
}
delete action.context.notifications;
}
this.action.doAction(action);
}
}
SpreadsheetFileUploader.components = {
FileUploader,
};
SpreadsheetFileUploader.template = "spreadsheet_oca.SpreadsheetFileUploader";
SpreadsheetFileUploader.props = {
...standardWidgetProps,
acceptedFileExtensions: {type: String, optional: true},
record: {type: Object, optional: true},
togglerTemplate: {type: String, optional: true},
slots: {type: Object, optional: true},
};
SpreadsheetFileUploader.defaultProps = {
acceptedFileExtensions:
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
};
export class SpreadsheetListController extends ListController {}
SpreadsheetListController.components = {
...ListController.components,
SpreadsheetFileUploader,
};
export const SpreadsheetListView = {
...listView,
Controller: SpreadsheetListController,
buttonTemplate: "spreadsheet_oca.ListView.Buttons",
};

registry.category("views").add("spreadsheet_tree", SpreadsheetListView);
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="spreadsheet_oca.SpreadsheetFileUploader" owl="1">
<div
t-att-class="props.record and props.record.data ? 'oe_kanban_color_' + props.record.data.color : ''"
>
<FileUploader
acceptedFileExtensions="props.acceptedFileExtensions"
fileUploadClass="'spreadsheet_file_uploader'"
multiUpload="true"
onUploaded.bind="onFileUploaded"
onUploadComplete.bind="onUploadComplete"
>
<t t-set-slot="toggler">
<t
t-if="props.togglerTemplate"
t-call="{{ props.togglerTemplate }}"
/>
<t t-else="" t-slot="default" />
</t>
<t t-slot="extra" />
</FileUploader>
</div>
</t>
<t
t-name="spreadsheet_oca.ListView.Buttons"
t-inherit="web.ListView.Buttons"
t-inherit-mode="primary"
owl="1"
>
<xpath expr="//*[@class='btn btn-primary o_list_button_add']" position="after">
<SpreadsheetFileUploader>
<t t-set-slot="default">
<button
type="button"
class="btn btn-secondary o_button_upload_bill"
>
Upload XLSX
</button>
</t>
</SpreadsheetFileUploader>
</xpath>
</t>
</templates>
2 changes: 1 addition & 1 deletion spreadsheet_oca/views/spreadsheet_spreadsheet.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<field name="name">spreadsheet.spreadsheet.tree (in spreadsheet_oca)</field>
<field name="model">spreadsheet.spreadsheet</field>
<field name="arch" type="xml">
<tree>
<tree js_class="spreadsheet_tree">
<field name="name" />
<button
name="open_spreadsheet"
Expand Down

0 comments on commit 13cd33e

Please sign in to comment.