Initial commit: Odoomates Odoo packages (12 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:49:21 +02:00
commit 3b38c49bf0
526 changed files with 34983 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,023 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="70" height="70" viewBox="0 0 70 70"><defs><path id="a" d="M4 0h61c4 0 5 1 5 5v60c0 4-1 5-5 5H4c-3 0-4-1-4-5V5c0-4 1-5 4-5z"/><linearGradient id="c" x1="100%" x2="0%" y1="0%" y2="100%"><stop offset="0%" stop-color="#DA956B"/><stop offset="100%" stop-color="#CC7039"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><g mask="url(#b)"><path fill="url(#c)" d="M0 0H70V70H0z"/><path fill="#FFF" fill-opacity=".383" d="M4 1h61c2.667 0 4.333.667 5 2V0H0v3c.667-1.333 2-2 4-2z"/><path fill="#393939" d="M4 69c-2 0-4-.146-4-4.09V40.738L18.16 24H52l1 2.045v6.137l-10.585 11.3 10.05 4.09L37.071 69H4z" opacity=".324"/><path fill="#000" fill-opacity=".383" d="M4 69h61c2.667 0 4.333-1 5-3v4H0v-4c.667 2 2 3 4 3z"/><path fill="#000" d="M53 42.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V28.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 35.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 40.695z" opacity=".3"/><path fill="#FFF" d="M53 40.084v5.66c0 1.837-1.111 3.34-3.556 3.34h-28c-2.466 0-4.444-1.503-4.444-3.34V26.34c0-1.837 1.978-3.34 4.444-3.34H49c2.444 0 4 1.368 4 3.205v5.88H37c-2.667 0-4 1.857-4 3.957 0 2.1 1.333 4.042 4 4.042h16zm-15-1.39a2.656 2.656 0 0 1-2.667-2.652A2.656 2.656 0 0 1 38 33.39a2.656 2.656 0 0 1 2.667 2.653A2.656 2.656 0 0 1 38 38.695z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,84 @@
<section class="oe_container oe_dark">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;color:#2C0091"><b>Odoo 16 Asset Management</b></h2>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="text-align:center;">
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Manage assets owned by a company or a person.</span>
</p><br/>
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Keeps track of depreciation's, and creates corresponding journal entries</span>
</p><br/>
</div>
<br/>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_centeralign oe_websiteonly">
<h4 class="oe_slogan"><a href="https://www.youtube.com/watch?v=KudvDOTvx2I" target="_blank" style="color: #FFFFFF !important; border-radius: 0; background-color: #9c676e; border-color: #005ca7; padding: 15px; font-weight: bold;">
<i class="fa fa-youtube"></i>
Watch on YouTube
</a></h4>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Asset Category</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="asset_types.png">
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h3 class="oe_slogan" style="color:#332c3c;font-size: 28px;">Assets</h3>
<div class="oe_demo oe_picture oe_screenshot">
<img src="assets.png">
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<section class="oe_container oe_dark">
<div class="oe_row ">
<div class="oe_slogan text-center">
<img src="odoo_mates.png"/>
<div style="color:#269900;">
<h3 style="color:#2C0091;font-size: 25px;">If you need any help or want more features, just contact us:</h3><br>
<h3 style="color:#2C0091;font-size: 20px;">Email: <a href="odoomates@gmail.com">odoomates@gmail.com</a> <br></h3>
</div>
<div class="oe_slogan">
<h2>
<a target="_blank" href="https://www.facebook.com/odoomate/" target="new">
<i class="fa fa-facebook-square" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://twitter.com/odoomates/" target="new">
<i class="fa fa-twitter" style="font-size:38px;"></i>
</a>
<a href="#" target="_blank">
<i class="fa fa-linkedin" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://www.youtube.com/channel/UCVKlUZP7HAhdQgs-9iTJklQ">
<i class="fa fa-youtube-play" style="font-size:38px;"></i>
</a>
</h2>
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

@ -0,0 +1,87 @@
odoo.define('om_account_asset.widget', function(require) {
"use strict";
/**
* The purpose of this widget is to shows a toggle button on depreciation and
* installment lines for posted/unposted line. When clicked, it calls the method
* create_move on the object account.asset.depreciation.line.
* Note that this widget can only work on the account.asset.depreciation.line
* model as some of its fields are harcoded.
*/
var AbstractField = require('web.AbstractField');
var core = require('web.core');
var registry = require('web.field_registry');
var _t = core._t;
var AccountAssetWidget = AbstractField.extend({
events: _.extend({}, AbstractField.prototype.events, {
'click': '_onClick',
}),
description: "",
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @override
*/
isSet: function () {
return true; // it should always be displayed, whatever its value
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
* @private
*/
_render: function () {
var className = '';
var disabled = true;
var title;
if (this.recordData.move_posted_check) {
className = 'o_is_posted';
title = _t('Posted');
} else if (this.recordData.move_check) {
className = 'o_unposted';
title = _t('Accounting entries waiting for manual verification');
} else {
disabled = false;
title = _t('Unposted');
}
var $button = $('<button/>', {
type: 'button',
title: title,
disabled: disabled,
}).addClass('btn btn-link fa fa-circle o_deprec_lines_toggler ' + className);
this.$el.html($button);
},
//--------------------------------------------------------------------------
// Handlers
//--------------------------------------------------------------------------
/**
* @private
* @param {MouseEvent} event
*/
_onClick: function (event) {
event.stopPropagation();
this.trigger_up('button_clicked', {
attrs: {
name: 'create_move',
type: 'object',
},
record: this.record,
});
},
});
registry.add("deprec_lines_toggler", AccountAssetWidget);
});

View file

@ -0,0 +1,9 @@
.o_web_client .o_deprec_lines_toggler {
color: theme-color('danger');
&.o_is_posted {
color: theme-color('success');
}
&.o_unposted {
color: theme-color('warning');
}
}

View file

@ -0,0 +1,168 @@
odoo.define('om_account_asset.widget_tests', function (require) {
"use strict";
var FormView = require('web.FormView');
var testUtils = require('web.test_utils');
var createView = testUtils.createView;
QUnit.module('fields', {}, function () {
QUnit.module('om_account_asset', {
beforeEach: function () {
this.data = {
asset: {
fields: {
display_name: { string: "Displayed name", type: "char" },
line_ids: {
string: "Lines",
type: "one2many",
relation: 'line',
relation_field: 'asset_id',
},
},
records: [{
id: 1,
display_name: "asset name",
line_ids: [1, 2, 3, 4],
}],
},
line: {
fields: {
move_check: {string: "Move Check", type: 'boolean'},
move_posted_check: {string: "Move Posted Check", type: 'boolean'},
asset_id: {string: "Asset", type: 'many2one', relation: 'asset'},
},
records: [{
id: 1,
move_check: true,
move_posted_check: true,
}, {
id: 2,
move_check: false,
move_posted_check: true,
}, {
id: 3,
move_check: true,
move_posted_check: false,
}, {
id: 4,
move_check: false,
move_posted_check: false,
}],
},
};
}
});
QUnit.test('basic rendering', function (assert) {
assert.expect(18);
var form = createView({
View: FormView,
model: 'asset',
data: this.data,
arch: '<form string="Asset">' +
'<sheet>' +
'<field name="display_name"/>' +
'<field name="line_ids">' +
'<tree>' +
'<field name="move_check" widget="deprec_lines_toggler"/>' +
'<field name="move_posted_check" invisible="1"/>' +
'</tree>' +
'</field>' +
'</sheet>' +
'</form>',
res_id: 1,
});
// check the header
assert.strictEqual(form.$('thead th').text(), "", "toggler column should have no title");
// check the classnames
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(0) button').hasClass('o_is_posted'),
"first line toggler should have classname 'o_is_posted'");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(0) button').hasClass('o_unposted'),
"first line toggler should not have classname 'o_unposted'");
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(1) button').hasClass('o_is_posted'),
"second line toggler should have classname 'o_is_posted'");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(1) button').hasClass('o_unposted'),
"second line toggler should not have classname 'o_unposted'");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(2) button').hasClass('o_is_posted'),
"third line toggler should not have classname 'o_is_posted'");
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(2) button').hasClass('o_unposted'),
"third line toggler should have classname 'o_unposted'");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(3) button').hasClass('o_is_posted'),
"fourth line toggler should not have classname 'o_is_posted'");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(3) button').hasClass('o_unposted'),
"fourth line toggler should not have classname 'o_unposted'");
// check the titles
assert.strictEqual(form.$('.o_deprec_lines_toggler_cell:nth(0) button').attr('title'),
'Posted', "first line toggler should have correct title");
assert.strictEqual(form.$('.o_deprec_lines_toggler_cell:nth(1) button').attr('title'),
'Posted', "second line toggler should have correct title");
assert.strictEqual(form.$('.o_deprec_lines_toggler_cell:nth(2) button').attr('title'),
'Accounting entries waiting for manual verification',
"third line toggler should have correct title");
assert.strictEqual(form.$('.o_deprec_lines_toggler_cell:nth(3) button').attr('title'),
'Unposted', "fourth line toggler should have correct title");
// check disabled property
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(0) button').attr('disabled'),
"first line toggle should be disabled");
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(1) button').attr('disabled'),
"second line toggle should be disabled");
assert.ok(form.$('.o_deprec_lines_toggler_cell:nth(2) button').attr('disabled'),
"third line toggle should be disabled");
assert.ok(!form.$('.o_deprec_lines_toggler_cell:nth(3) button').attr('disabled'),
"fourth line toggle should not be disabled");
// check the visibility: the widget should always be visible, regardless its value
assert.strictEqual(form.$('.o_deprec_lines_toggler:visible').length, 4,
"all togglers should be visible");
form.destroy();
});
QUnit.test('click events are correctly triggered', function (assert) {
assert.expect(2);
var form = createView({
View: FormView,
model: 'asset',
data: this.data,
arch: '<form string="Asset">' +
'<sheet>' +
'<field name="display_name"/>' +
'<field name="line_ids">' +
'<tree>' +
'<field name="move_check" widget="deprec_lines_toggler"/>' +
'<field name="move_posted_check" invisible="1"/>' +
'</tree>' +
'</field>' +
'</sheet>' +
'</form>',
res_id: 1,
intercepts: {
execute_action: function (event) {
var data = event.data;
assert.strictEqual(data.env.model, 'line', "should have correct model");
assert.strictEqual(data.action_data.name, 'create_move',
"should call correct method");
},
}
});
// click on last row toggler
form.$('.o_deprec_lines_toggler_cell:nth(3) button').click();
form.destroy();
});
});
});