@@ -107,6 +107,7 @@ You could use this simplified accounting in case you work with an (external) acc
|
||||
'account/static/src/js/legacy_section_and_note_fields_backend.js',
|
||||
'account/static/src/js/tours/account.js',
|
||||
'account/static/src/js/bills_upload.js',
|
||||
'account/static/src/js/legacy_bills_upload.js',
|
||||
'account/static/src/js/account_selection.js',
|
||||
'account/static/src/js/open_move_widget.js',
|
||||
'account/static/src/js/account_move_form.js',
|
||||
|
||||
@@ -1,160 +1,157 @@
|
||||
odoo.define('account.upload.document', function (require) {
|
||||
"use strict";
|
||||
/** @odoo-module **/
|
||||
|
||||
var core = require('web.core');
|
||||
var qweb = core.qweb;
|
||||
var ListController = require('web.ListController');
|
||||
var ListView = require('web.ListView');
|
||||
var KanbanController = require('web.KanbanController');
|
||||
var KanbanView = require('web.KanbanView');
|
||||
var viewRegistry = require('web.view_registry');
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { listView } from "@web/views/list/list_view";
|
||||
import { ListRenderer } from "@web/views/list/list_renderer";
|
||||
import { ListController } from "@web/views/list/list_controller";
|
||||
import { kanbanView } from "@web/views/kanban/kanban_view";
|
||||
import { KanbanRenderer } from "@web/views/kanban/kanban_renderer";
|
||||
import { KanbanController } from "@web/views/kanban/kanban_controller";
|
||||
import { KanbanRecord } from "@web/views/kanban/kanban_record";
|
||||
import { FileUploader } from "@web/views/fields/file_handler";
|
||||
|
||||
var UploadDocumentMixin = {
|
||||
events: {
|
||||
'click .o_button_upload_document': '_onUpload',
|
||||
'change .o_account_document_upload .o_form_binary_form': '_onAddAttachment',
|
||||
'drop .o_drop_area': '_onDrop',
|
||||
'dragenter .o_content': '_highlight',
|
||||
'dragleave .o_drop_area': '_unhighlight',
|
||||
'dragover .o_drop_area': '_clear',
|
||||
},
|
||||
const { Component, useState } = owl;
|
||||
|
||||
start: async function () {
|
||||
// define a unique uploadId and a callback method
|
||||
this.fileUploadID = _.uniqueId('account_bill_file_upload');
|
||||
$(window).on(this.fileUploadID, this._onFileUploaded.bind(this));
|
||||
let result = await this._super.apply(this, arguments);
|
||||
await this.$(this._dropZone).prepend($(qweb.render('account.DocumentDropZone')));
|
||||
return result;
|
||||
},
|
||||
|
||||
reload: async function () {
|
||||
let result = await this._super.apply(this, arguments);
|
||||
await this.$(this._dropZone).prepend($(qweb.render('account.DocumentDropZone')));
|
||||
return result;
|
||||
},
|
||||
|
||||
_onAddAttachment: function (ev) {
|
||||
// Auto submit form once we've selected an attachment
|
||||
var $input = $(ev.currentTarget).find('input.o_input_file');
|
||||
if ($input.val() !== '') {
|
||||
var $binaryForm = this.$('.o_account_document_upload form.o_form_binary_form');
|
||||
$binaryForm.submit();
|
||||
}
|
||||
},
|
||||
|
||||
_onFileUploaded: function () {
|
||||
// Callback once attachment have been created, create a document with attachment ids
|
||||
var self = this;
|
||||
var attachments = Array.prototype.slice.call(arguments, 1);
|
||||
// Get id from result
|
||||
var attachent_ids = attachments.reduce(function(filtered, record) {
|
||||
if (record.id) {
|
||||
filtered.push(record.id);
|
||||
}
|
||||
return filtered;
|
||||
}, []);
|
||||
return this._rpc({
|
||||
model: 'account.journal',
|
||||
method: 'create_document_from_attachment',
|
||||
args: ["", attachent_ids],
|
||||
context: this.initialState.context,
|
||||
}).then(function(result) {
|
||||
self.do_action(result);
|
||||
}).catch(function () {
|
||||
// Reset the file input, allowing to select again the same file if needed
|
||||
self.$('.o_account_document_upload .o_input_file').val('');
|
||||
});
|
||||
},
|
||||
|
||||
_createForm: function() {
|
||||
// If hidden upload form don't exists, create it
|
||||
var $formContainer = this.$('.o_content').find('.o_account_document_upload');
|
||||
if (!$formContainer.length) {
|
||||
$formContainer = $(qweb.render('account.DocumentsHiddenUploadForm', {widget: this}));
|
||||
$formContainer.appendTo(this.$('.o_content'));
|
||||
}
|
||||
},
|
||||
|
||||
_onUpload: function (ev) {
|
||||
this._createForm();
|
||||
// Trigger the input to select a file
|
||||
this.$('.o_account_document_upload .o_input_file').click();
|
||||
},
|
||||
|
||||
_highlight: function(ev) {
|
||||
$('.o_drop_area').show();
|
||||
},
|
||||
|
||||
_unhighlight: function(ev) {
|
||||
$('.o_drop_area').hide();
|
||||
},
|
||||
|
||||
_clear: function(ev) {
|
||||
ev.preventDefault();
|
||||
},
|
||||
|
||||
_onDrop: function (ev) {
|
||||
ev.preventDefault();
|
||||
this._createForm();
|
||||
if (ev.originalEvent.dataTransfer.files.length) {
|
||||
this.$('.o_account_document_upload .o_input_file')[0].files = ev.originalEvent.dataTransfer.files;
|
||||
this.$('.o_form_binary_form')[0].submit();
|
||||
}
|
||||
this._unhighlight(ev);
|
||||
},
|
||||
export class AccountFileUploader extends Component {
|
||||
setup() {
|
||||
this.orm = useService("orm");
|
||||
this.action = useService("action");
|
||||
this.attachmentIdsToProcess = [];
|
||||
}
|
||||
|
||||
var DocumentsListView = ListView.extend({
|
||||
config: Object.assign({}, ListView.prototype.config, {
|
||||
Controller: ListController.extend({_dropZone: '.o_content'}, UploadDocumentMixin, {
|
||||
buttons_template: 'DocumentsListView.buttons',
|
||||
events: Object.assign({}, ListController.prototype.events, UploadDocumentMixin.events),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
async onFileUploaded(file) {
|
||||
let att_data = {
|
||||
name: file.name,
|
||||
mimetype: file.type,
|
||||
datas: file.data,
|
||||
};
|
||||
const att_id = await this.orm.create("ir.attachment", att_data, {
|
||||
...this.props.extraContext, ...this.env.searchModel.context,
|
||||
});
|
||||
this.attachmentIdsToProcess.push(att_id);
|
||||
}
|
||||
|
||||
var DocumentsKanbanView = KanbanView.extend({
|
||||
config: Object.assign({}, KanbanView.prototype.config, {
|
||||
Controller: KanbanController.extend({_dropZone: '.o_content'}, UploadDocumentMixin, {
|
||||
buttons_template: 'DocumentsKanbanView.buttons',
|
||||
events: Object.assign({}, KanbanController.prototype.events, UploadDocumentMixin.events),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
async onUploadComplete() {
|
||||
const action = await this.orm.call("account.journal", "create_document_from_attachment", ["", this.attachmentIdsToProcess], {
|
||||
context: { ...this.props.extraContext, ...this.env.searchModel.context },
|
||||
});
|
||||
this.attachmentIdsToProcess = [];
|
||||
this.action.doAction(action);
|
||||
}
|
||||
}
|
||||
AccountFileUploader.components = {
|
||||
FileUploader,
|
||||
};
|
||||
AccountFileUploader.template = "account.AccountFileUploader";
|
||||
|
||||
var DashboardKanbanController = KanbanController.extend({_dropZone: '.o_kanban_record'}, UploadDocumentMixin, {
|
||||
events: Object.assign({}, KanbanController.prototype.events, UploadDocumentMixin.events),
|
||||
export class AccountDropZone extends Component {
|
||||
setup() {
|
||||
this.notificationService = useService("notification");
|
||||
}
|
||||
|
||||
_setJournalContext: function(ev) {
|
||||
var kanbanRecord = $(ev.currentTarget).closest('.o_kanban_record').data('record');
|
||||
this.initialState.context['default_journal_id'] = kanbanRecord.id;
|
||||
let journal_type = kanbanRecord.state.data.type;
|
||||
if (journal_type == 'sale') {
|
||||
this.initialState.context['default_move_type'] = 'out_invoice';
|
||||
} else if (journal_type == 'purchase') {
|
||||
this.initialState.context['default_move_type'] = 'in_invoice';
|
||||
}
|
||||
},
|
||||
onDrop(ev) {
|
||||
const selector = '.account_file_uploader.o_input_file.o_hidden';
|
||||
// look for the closest uploader Input as it may have a context
|
||||
let uploadInput = ev.target.closest('.o_drop_area').parentElement.querySelector(selector) || document.querySelector(selector);
|
||||
let files = ev.dataTransfer ? ev.dataTransfer.files : false;
|
||||
if (uploadInput && !!files) {
|
||||
uploadInput.files = ev.dataTransfer.files;
|
||||
uploadInput.dispatchEvent(new Event("change"));
|
||||
} else {
|
||||
this.notificationService.add(
|
||||
this.env._t("Could not upload files"),
|
||||
{
|
||||
type: "danger",
|
||||
});
|
||||
}
|
||||
this.props.hideZone();
|
||||
}
|
||||
}
|
||||
AccountDropZone.defaultProps = {
|
||||
hideZone: () => {},
|
||||
};
|
||||
AccountDropZone.template = "account.DropZone";
|
||||
|
||||
_onUpload: function (ev) {
|
||||
this._setJournalContext(ev);
|
||||
UploadDocumentMixin._onUpload.apply(this, arguments);
|
||||
},
|
||||
// Account Move List View
|
||||
export class AccountMoveUploadListRenderer extends ListRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.state.dropzoneVisible = false;
|
||||
}
|
||||
}
|
||||
AccountMoveUploadListRenderer.template = "account.ListRenderer";
|
||||
AccountMoveUploadListRenderer.components = {
|
||||
...ListRenderer.components,
|
||||
AccountDropZone,
|
||||
};
|
||||
|
||||
_onDrop: function (ev) {
|
||||
this._setJournalContext(ev);
|
||||
UploadDocumentMixin._onDrop.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
export class AccountMoveUploadListController extends ListController {}
|
||||
AccountMoveUploadListController.components = {
|
||||
...ListController.components,
|
||||
AccountFileUploader,
|
||||
};
|
||||
|
||||
var DashboardKanbanView = KanbanView.extend({
|
||||
config: Object.assign({}, KanbanView.prototype.config, {
|
||||
Controller: DashboardKanbanController,
|
||||
}),
|
||||
});
|
||||
export const AccountMoveUploadListView = {
|
||||
...listView,
|
||||
Controller: AccountMoveUploadListController,
|
||||
Renderer: AccountMoveUploadListRenderer,
|
||||
buttonTemplate: "account.ListView.Buttons",
|
||||
};
|
||||
|
||||
viewRegistry.add('account_tree', DocumentsListView);
|
||||
viewRegistry.add('account_documents_kanban', DocumentsKanbanView);
|
||||
viewRegistry.add('account_dashboard_kanban', DashboardKanbanView);
|
||||
});
|
||||
// Account Move Kanban View
|
||||
export class AccountMoveUploadKanbanRenderer extends KanbanRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.state.dropzoneVisible = false;
|
||||
}
|
||||
}
|
||||
AccountMoveUploadKanbanRenderer.template = "account.KanbanRenderer";
|
||||
AccountMoveUploadKanbanRenderer.components = {
|
||||
...KanbanRenderer.components,
|
||||
AccountDropZone,
|
||||
};
|
||||
|
||||
export class AccountMoveUploadKanbanController extends KanbanController {}
|
||||
AccountMoveUploadKanbanController.components = {
|
||||
...KanbanController.components,
|
||||
AccountFileUploader,
|
||||
};
|
||||
|
||||
export const AccountMoveUploadKanbanView = {
|
||||
...kanbanView,
|
||||
Controller: AccountMoveUploadKanbanController,
|
||||
Renderer: AccountMoveUploadKanbanRenderer,
|
||||
buttonTemplate: "account.KanbanView.Buttons",
|
||||
};
|
||||
|
||||
// Accounting Dashboard
|
||||
export class DashboardKanbanRecord extends KanbanRecord {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.state = useState({
|
||||
dropzoneVisible: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
DashboardKanbanRecord.components = {
|
||||
...DashboardKanbanRecord.components,
|
||||
AccountDropZone,
|
||||
AccountFileUploader,
|
||||
};
|
||||
DashboardKanbanRecord.template = "account.DashboardKanbanRecord";
|
||||
|
||||
export class DashboardKanbanRenderer extends KanbanRenderer {}
|
||||
DashboardKanbanRenderer.components = {
|
||||
...KanbanRenderer.components,
|
||||
KanbanRecord: DashboardKanbanRecord,
|
||||
};
|
||||
|
||||
export const DashboardKanbanView = {
|
||||
...kanbanView,
|
||||
Renderer: DashboardKanbanRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("account_tree", AccountMoveUploadListView);
|
||||
registry.category("views").add("account_documents_kanban", AccountMoveUploadKanbanView);
|
||||
registry.category("views").add("account_dashboard_kanban", DashboardKanbanView);
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
odoo.define('account.upload.document', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var qweb = core.qweb;
|
||||
var ListController = require('web.ListController');
|
||||
var ListView = require('web.ListView');
|
||||
var KanbanController = require('web.KanbanController');
|
||||
var KanbanView = require('web.KanbanView');
|
||||
var viewRegistry = require('web.view_registry');
|
||||
|
||||
var UploadDocumentMixin = {
|
||||
events: {
|
||||
'click .o_button_upload_document': '_onUpload',
|
||||
'change .o_account_document_upload .o_form_binary_form': '_onAddAttachment',
|
||||
'drop .o_drop_area': '_onDrop',
|
||||
'dragenter .o_content': '_highlight',
|
||||
'dragleave .o_drop_area': '_unhighlight',
|
||||
'dragover .o_drop_area': '_clear',
|
||||
},
|
||||
|
||||
start: async function () {
|
||||
// define a unique uploadId and a callback method
|
||||
this.fileUploadID = _.uniqueId('account_bill_file_upload');
|
||||
$(window).on(this.fileUploadID, this._onFileUploaded.bind(this));
|
||||
let result = await this._super.apply(this, arguments);
|
||||
await this.$(this._dropZone).prepend($(qweb.render('account.DocumentDropZone')));
|
||||
return result;
|
||||
},
|
||||
|
||||
reload: async function () {
|
||||
let result = await this._super.apply(this, arguments);
|
||||
await this.$(this._dropZone).prepend($(qweb.render('account.DocumentDropZone')));
|
||||
return result;
|
||||
},
|
||||
|
||||
_onAddAttachment: function (ev) {
|
||||
// Auto submit form once we've selected an attachment
|
||||
var $input = $(ev.currentTarget).find('input.o_input_file');
|
||||
if ($input.val() !== '') {
|
||||
var $binaryForm = this.$('.o_account_document_upload form.o_form_binary_form');
|
||||
$binaryForm.submit();
|
||||
}
|
||||
},
|
||||
|
||||
_onFileUploaded: function () {
|
||||
// Callback once attachment have been created, create a document with attachment ids
|
||||
var self = this;
|
||||
var attachments = Array.prototype.slice.call(arguments, 1);
|
||||
// Get id from result
|
||||
var attachent_ids = attachments.reduce(function(filtered, record) {
|
||||
if (record.id) {
|
||||
filtered.push(record.id);
|
||||
}
|
||||
return filtered;
|
||||
}, []);
|
||||
return this._rpc({
|
||||
model: 'account.journal',
|
||||
method: 'create_document_from_attachment',
|
||||
args: ["", attachent_ids],
|
||||
context: this.initialState.context,
|
||||
}).then(function(result) {
|
||||
self.do_action(result);
|
||||
}).catch(function () {
|
||||
// Reset the file input, allowing to select again the same file if needed
|
||||
self.$('.o_account_document_upload .o_input_file').val('');
|
||||
});
|
||||
},
|
||||
|
||||
_createForm: function() {
|
||||
// If hidden upload form don't exists, create it
|
||||
var $formContainer = this.$('.o_content').find('.o_account_document_upload');
|
||||
if (!$formContainer.length) {
|
||||
$formContainer = $(qweb.render('account.DocumentsHiddenUploadForm', {widget: this}));
|
||||
$formContainer.appendTo(this.$('.o_content'));
|
||||
}
|
||||
},
|
||||
|
||||
_onUpload: function (ev) {
|
||||
this._createForm();
|
||||
// Trigger the input to select a file
|
||||
this.$('.o_account_document_upload .o_input_file').click();
|
||||
},
|
||||
|
||||
_highlight: function(ev) {
|
||||
$('.o_drop_area').show();
|
||||
},
|
||||
|
||||
_unhighlight: function(ev) {
|
||||
$('.o_drop_area').hide();
|
||||
},
|
||||
|
||||
_clear: function(ev) {
|
||||
ev.preventDefault();
|
||||
},
|
||||
|
||||
_onDrop: function (ev) {
|
||||
ev.preventDefault();
|
||||
this._createForm();
|
||||
if (ev.originalEvent.dataTransfer.files.length) {
|
||||
this.$('.o_account_document_upload .o_input_file')[0].files = ev.originalEvent.dataTransfer.files;
|
||||
this.$('.o_form_binary_form')[0].submit();
|
||||
}
|
||||
this._unhighlight(ev);
|
||||
},
|
||||
}
|
||||
|
||||
var DocumentsListView = ListView.extend({
|
||||
config: Object.assign({}, ListView.prototype.config, {
|
||||
Controller: ListController.extend({_dropZone: '.o_content'}, UploadDocumentMixin, {
|
||||
buttons_template: 'DocumentsListView.buttons',
|
||||
events: Object.assign({}, ListController.prototype.events, UploadDocumentMixin.events),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
var DocumentsKanbanView = KanbanView.extend({
|
||||
config: Object.assign({}, KanbanView.prototype.config, {
|
||||
Controller: KanbanController.extend({_dropZone: '.o_content'}, UploadDocumentMixin, {
|
||||
buttons_template: 'DocumentsKanbanView.buttons',
|
||||
events: Object.assign({}, KanbanController.prototype.events, UploadDocumentMixin.events),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
var DashboardKanbanController = KanbanController.extend({_dropZone: '.o_kanban_record'}, UploadDocumentMixin, {
|
||||
events: Object.assign({}, KanbanController.prototype.events, UploadDocumentMixin.events),
|
||||
|
||||
_setJournalContext: function(ev) {
|
||||
var kanbanRecord = $(ev.currentTarget).closest('.o_kanban_record').data('record');
|
||||
this.initialState.context['default_journal_id'] = kanbanRecord.id;
|
||||
let journal_type = kanbanRecord.state.data.type;
|
||||
if (journal_type == 'sale') {
|
||||
this.initialState.context['default_move_type'] = 'out_invoice';
|
||||
} else if (journal_type == 'purchase') {
|
||||
this.initialState.context['default_move_type'] = 'in_invoice';
|
||||
}
|
||||
},
|
||||
|
||||
_onUpload: function (ev) {
|
||||
this._setJournalContext(ev);
|
||||
UploadDocumentMixin._onUpload.apply(this, arguments);
|
||||
},
|
||||
|
||||
_onDrop: function (ev) {
|
||||
this._setJournalContext(ev);
|
||||
UploadDocumentMixin._onDrop.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
var DashboardKanbanView = KanbanView.extend({
|
||||
config: Object.assign({}, KanbanView.prototype.config, {
|
||||
Controller: DashboardKanbanController,
|
||||
}),
|
||||
});
|
||||
|
||||
viewRegistry.add('account_tree', DocumentsListView);
|
||||
viewRegistry.add('account_documents_kanban', DocumentsKanbanView);
|
||||
viewRegistry.add('account_dashboard_kanban', DashboardKanbanView);
|
||||
});
|
||||
@@ -1,5 +1,4 @@
|
||||
.o_drop_area {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
|
||||
@@ -1,37 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<templates>
|
||||
<t t-name="account.DocumentsHiddenUploadForm">
|
||||
<div class="d-none o_account_document_upload">
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="multi_upload" t-value="true"/>
|
||||
<t t-set="fileupload_id" t-value="widget.fileUploadID"/>
|
||||
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
|
||||
<input type="hidden" name="model" value=""/>
|
||||
<input type="hidden" name="id" value="0"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-extend="ListView.buttons" t-name="DocumentsListView.buttons">
|
||||
<t t-jquery="button.o_list_button_add" t-operation="after">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_document">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-extend="KanbanView.buttons" t-name="DocumentsKanbanView.buttons">
|
||||
<t t-jquery="button" t-operation="after">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_document">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="account.DocumentDropZone">
|
||||
<div class="o_drop_area">
|
||||
<t t-name="account.DropZone" owl="1">
|
||||
<div t-if="props.visible"
|
||||
t-attf-class="o_drop_area"
|
||||
t-on-dragover.prevent="()=>{}"
|
||||
t-on-dragleave="props.hideZone"
|
||||
t-on-drop.prevent="onDrop">
|
||||
<i class="fa fa-upload fa-10x"></i>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="account.AccountFileUploader" owl="1">
|
||||
<div>
|
||||
<FileUploader
|
||||
acceptedFileExtensions="props.acceptedFileExtensions"
|
||||
fileUploadClass="'account_file_uploader'"
|
||||
multiUpload="true"
|
||||
onUploaded.bind="onFileUploaded"
|
||||
onUploadComplete.bind="onUploadComplete">
|
||||
<t t-set-slot="toggler">
|
||||
<t t-slot="toggleButton"/>
|
||||
</t>
|
||||
</FileUploader>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="account.ListRenderer" t-inherit="web.ListRenderer" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[@t-ref='root']" position="before">
|
||||
<AccountDropZone
|
||||
visible="state.dropzoneVisible"
|
||||
hideZone="() => state.dropzoneVisible = false"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@t-ref='root']" position="attributes">
|
||||
<attribute name="t-on-dragenter.stop.prevent">() => state.dropzoneVisible = true</attribute>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="account.KanbanRenderer" t-inherit="web.KanbanRenderer" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//div[@t-ref='root']" position="before">
|
||||
<AccountDropZone
|
||||
visible="state.dropzoneVisible"
|
||||
hideZone="() => state.dropzoneVisible = false"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@t-ref='root']" position="attributes">
|
||||
<attribute name="t-on-dragenter.stop.prevent">() => state.dropzoneVisible = true</attribute>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="account.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">
|
||||
<AccountFileUploader extraContext="props.context">
|
||||
<t t-set-slot="toggleButton">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_bill">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</AccountFileUploader>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="account.KanbanView.Buttons" t-inherit="web.KanbanView.Buttons" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//*[@class='btn btn-primary o-kanban-button-new']" position="after">
|
||||
<AccountFileUploader extraContext="props.context">
|
||||
<t t-set-slot="toggleButton">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_bill">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</AccountFileUploader>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="account.DashboardKanbanRecord" owl="1">
|
||||
<div
|
||||
role="article"
|
||||
t-att-class="getRecordClasses()"
|
||||
t-att-data-id="props.canResequence and props.record.id"
|
||||
t-att-tabindex="props.record.model.useSampleModel ? -1 : 0"
|
||||
t-on-click="onGlobalClick"
|
||||
t-on-dragenter.stop.prevent="() => state.dropzoneVisible = true"
|
||||
t-ref="root">
|
||||
<t t-call="{{ templates['kanban-box'] }}"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<templates>
|
||||
<t t-name="account.DocumentsHiddenUploadForm">
|
||||
<div class="d-none o_account_document_upload">
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="multi_upload" t-value="true"/>
|
||||
<t t-set="fileupload_id" t-value="widget.fileUploadID"/>
|
||||
<t t-set="fileupload_action" t-translation="off">/web/binary/upload_attachment</t>
|
||||
<input type="hidden" name="model" value=""/>
|
||||
<input type="hidden" name="id" value="0"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-extend="ListView.buttons" t-name="DocumentsListView.buttons">
|
||||
<t t-jquery="button.o_list_button_add" t-operation="after">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_document">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-extend="KanbanView.buttons" t-name="DocumentsKanbanView.buttons">
|
||||
<t t-jquery="button" t-operation="after">
|
||||
<button type="button" class="btn btn-secondary o_button_upload_document">
|
||||
Upload
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-name="account.DocumentDropZone">
|
||||
<div class="o_drop_area">
|
||||
<i class="fa fa-upload fa-10x"></i>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -18,6 +18,7 @@
|
||||
<div t-attf-class="#{!selection_mode ? kanban_color(record.color.raw_value) : ''}">
|
||||
<t t-value="JSON.parse(record.kanban_dashboard.raw_value)" t-set="dashboard"/>
|
||||
<t t-value="record.type.raw_value" t-set="journal_type"/>
|
||||
<t t-call="AccountDropZoneUploader"/>
|
||||
<t t-call="JournalTop"/>
|
||||
<div t-att-class="'container o_kanban_card_content' + (dashboard.is_sample_data ? ' o_sample_data' : '')">
|
||||
<div class="row">
|
||||
@@ -36,6 +37,17 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="AccountDropZoneUploader" owl="1">
|
||||
<AccountDropZone
|
||||
visible="state.dropzoneVisible"
|
||||
hideZone="() => state.dropzoneVisible = false"/>
|
||||
<AccountFileUploader
|
||||
extraContext="{
|
||||
default_journal_id: record.id.raw_value,
|
||||
default_move_type: journal_type == 'sale' and 'out_invoice' or journal_type == 'purchase' and 'in_invoice' or 'entry'
|
||||
}"/>
|
||||
</t>
|
||||
|
||||
<t t-name="JournalTop">
|
||||
<div t-attf-class="o_kanban_card_header">
|
||||
<div class="o_kanban_card_header_title">
|
||||
|
||||
Reference in New Issue
Block a user