frist moduls odex30 account

This commit is contained in:
mohammed-alkhazrji 2026-01-05 01:17:42 +03:00
commit 9a432e947e
943 changed files with 145795 additions and 0 deletions

View File

@ -0,0 +1,33 @@
# Changelog
## [18.0.1.0.0] - 2026-01-02
### Migration from Odoo 14
- Replaced `internal_type` with `is_view_account` boolean field
- Replaced `user_type_id` with native `account_type` selection
- Updated all domain filters for compatibility
- Migrated report from old AbstractModel structure to new account.report framework
### Added
- Full Odoo 18 `account.report` integration
- Support for comparison periods in reports
- Journal filtering in reports
- Hierarchical account display in reports
- Automatic account code generation based on parent
- Level-based account hierarchy
### Changed
- Report now inherits from `account.report` instead of standalone AbstractModel
- View XML updated to Odoo 18 syntax (removed `attrs`, using `invisible`)
- Dependencies updated (now requires `account_reports`)
### Fixed
- Domain filters compatibility with Odoo 18
- Account creation with parent relationships
- Journal account creation with proper account types
### Technical
- Added `_parent_store` functionality for efficient hierarchy queries
- Implemented `format_value()` method for currency display
- Added balance calculation methods for reports
- Full support for multi-company environments

View File

@ -0,0 +1,105 @@
# Chart of Accounts Hierarchy - Odoo 18
## Description
This module provides hierarchical chart of accounts with parent-child relationships for Odoo 18,
including a complete Chart of Accounts report compatible with the new Odoo 18 reporting framework.
## Features
- ✅ Hierarchical chart of accounts with parent-child relationships
- ✅ Automatic account code generation
- ✅ View accounts support (parent accounts only)
- ✅ Fixed tree length support
- ✅ Customizable account code padding
- ✅ Integration with journal creation
- ✅ **Chart of Accounts Report** with Odoo 18 compatibility
## Migration from Odoo 14
This module has been fully migrated from Odoo 14 with the following major changes:
### Account Models:
- ❌ Removed `internal_type` field
- ✅ Added `is_view_account` boolean field
- ❌ Removed `user_type_id` (Many2one)
- ✅ Now using `account_type` (Selection field)
- ✅ Updated all domain filters
### Report Framework:
- ❌ Old: `AbstractModel` with `_name = 'account.coa.report'`
- ✅ New: `AbstractModel` inheriting from `account.report`
- ❌ Old: Simple `_get_lines()` method
- ✅ New: Advanced reporting with options, filters, and hierarchies
- ✅ Compatible with Odoo 18 `account_reports` module
## Installation
1. Make sure `account_reports` module is installed (Odoo Enterprise)
2. Copy this module to your Odoo addons directory
3. Update the apps list: `Settings → Apps → Update Apps List`
4. Install from Apps menu: Search "Chart of Accounts Hierarchy"
## Configuration
Navigate to: **Accounting → Configuration → Settings → Chart of Accounts Hierarchy Settings**
Available options:
- **Automatically Generate Account Codes**: Enable auto-generation based on parent
- **Use Fixed Length**: Enforce a specific tree depth
- **Account Code Padding**: Number of digits for padding
- **Bank/Cash Prefixes**: Define account code prefixes
## Usage
### Creating Hierarchical Accounts
1. Go to: **Accounting → Configuration → Chart of Accounts**
2. Create a parent account:
- Check "Is View Account"
- Set the account code (e.g., `1000`)
3. Create child accounts:
- Select the parent account in "Parent Account" field
- Code will be generated automatically (e.g., `10001`, `10002`)
### Viewing Reports
1. Go to: **Accounting → Reporting → Chart of Accounts**
2. Use filters to customize the view:
- Date range
- Journals
- Comparison periods
- Hierarchy view
## Technical Details
### New Fields in account.account:
- `parent_id`: Many2one to parent account
- `is_view_account`: Boolean for view accounts
- `level`: Integer showing hierarchy depth
- `auto_code`: Computed account code
- `child_ids`: One2many to child accounts
- `parent_path`: Hierarchical path (using `_parent_store`)
### Dependencies:
- `account` (Odoo Community)
- `account_reports` (Odoo Enterprise - required for reports)
## Troubleshooting
### Issue: Report not showing
**Solution**: Make sure `account_reports` module is installed
### Issue: Account codes not generating
**Solution**: Enable "Automatically Generate Account Codes" in settings
### Issue: Cannot create view accounts
**Solution**: Check "Is View Account" when creating parent accounts
## Support
For issues or questions, please contact your Odoo partner or open an issue on GitHub.
## Author
Your Company
## License
LGPL-3
## Version History
- **18.0.1.0.0**: Initial migration from Odoo 14 to Odoo 18
- Complete rewrite of account models
- New reporting framework implementation
- Full compatibility with Odoo 18 accounting

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models
from . import report

View File

@ -0,0 +1,55 @@
{
'name': 'Chart of Accounts Hierarchy - Odoo 18',
'version': '18.0.1.0.0',
'category': 'Accounting',
'summary': 'Hierarchical Chart of Accounts with Parent-Child Relationships',
'description': """
Chart of Accounts Hierarchy for Odoo 18
========================================
Features:
---------
* Hierarchical chart of accounts with parent-child relationships
* Automatic account code generation
* View accounts support (parent accounts only)
* Fixed tree length support
* Customizable account code padding
* Integration with journal creation
* Chart of Accounts report with hierarchy support
Migration from Odoo 14:
----------------------
* Replaced internal_type with account_type
* Replaced user_type_id with account_type field
* Added is_view_account boolean field
* Updated all domain filters
* Migrated account.report from AbstractModel to standard Model structure
* Compatible with Odoo 18 accounting framework
""",
'author': 'Your Company',
'website': 'https://www.yourcompany.com',
'depends': ['account', 'odex30_account_reports'],
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
'views/account_account_view.xml',
'views/res_config_settings_views.xml',
'data/account_report_data.xml',
],
'assets': {
'web.assets_backend': [
'account_chart_of_accounts/static/src/js/account_type_selection_extend.js',
'account_chart_of_accounts/static/src/js/filters_patch.js',
'account_chart_of_accounts/static/src/js/account_report.js',
'account_chart_of_accounts/static/src/xml/filter_full_hierarchy.xml',
],
'web.assets_frontend': [
'account_chart_of_accounts/static/src/scss/account_hierarchy.scss',
],
},
'installable': True,
'application': False,
'auto_install': False,
'license': 'LGPL-3',
}

View File

@ -0,0 +1,7 @@
<odoo>
<record id="odex30_account_reports.trial_balance_report" model="account.report">
<field name="filter_show_full_hierarchy" eval="True"/>
</record>
</odoo>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import account_account
from . import account_journal
from . import res_config_settings

View File

@ -0,0 +1,187 @@
from odoo import fields, models, api, _
from odoo.exceptions import UserError
from odoo.osv import expression
class AccountAccount(models.Model):
_inherit = "account.account"
_parent_name = "parent_id"
_parent_store = True
company_id = fields.Many2one('res.company', string='Company', required=True, readonly=True,
default=lambda self: self.env.company)
account_type = fields.Selection(
selection_add=[('view', 'View')],
ondelete={'view': 'cascade'}
)
automticAccountsCodes = fields.Boolean(
related='company_id.automticAccountsCodes',
)
internal_group = fields.Selection(
selection_add=[('view', 'View')],
ondelete={'view': lambda recs: recs.write({'internal_group': 'off'})}
)
parent_id = fields.Many2one(
comodel_name='account.account',
string='Parent Account',
domain="[('account_type', '=', 'view')]"
)
parent_path = fields.Char(index=True)
child_ids = fields.One2many(
'account.account', 'parent_id', 'Child Accounts'
)
auto_code = fields.Char(
compute='_get_code', default='0',
store=True, size=64, index=True
)
level = fields.Integer(
compute="_get_level", store=True, string='Level'
)
@api.depends('code', 'account_type')
def _compute_account_type(self):
view_accounts = self.filtered(lambda acc: acc.account_type == 'view')
other_accounts = self - view_accounts
if other_accounts:
super(AccountAccount, other_accounts)._compute_account_type()
@api.depends('account_type')
def _compute_internal_group(self):
"""Override to handle view type"""
for record in self:
if record.account_type == 'view':
record.internal_group = 'view'
else:
super(AccountAccount, record)._compute_internal_group()
@api.model
def _name_search(self, name, domain=None, operator='ilike', limit=100, order=None):
if domain is None:
domain = []
# استبدال internal_type بـ account_type في Odoo 18
domain = self._replace_internal_type_domain(domain)
if not self.env.context.get('show_view') and not self.env.context.get('import_file'):
domain += [('account_type', '!=', 'view')]
return super()._name_search(name, domain, operator, limit, order)
def _replace_internal_type_domain(self, domain):
"""استبدال internal_type بـ account_type"""
new_domain = []
for condition in domain:
if isinstance(condition, (list, tuple)) and len(condition) >= 3:
if condition[0] in ('internal_type', 'type') and condition[2] == 'view':
new_domain.append(('account_type', condition[1], 'view'))
elif condition[0] in ('internal_type', 'type') and condition[1] == '!=':
new_domain.append(('account_type', '!=', 'view'))
else:
new_domain.append(condition)
else:
new_domain.append(condition)
return new_domain
@api.depends('parent_id')
def _get_level(self):
for rec in self:
level = 0
if rec.parent_id:
level = rec.parent_id.level + 1
if rec.company_id.useFiexedTree and rec.company_id.chart_account_length:
if level > rec.company_id.chart_account_length:
raise UserError(
_('This account level is greater than the chart of account length.'))
rec.level = level
@api.depends('parent_id', 'code', 'parent_id.code')
def _get_code(self):
for rec in self:
if not rec.company_id.automticAccountsCodes and rec.code:
rec.auto_code = rec.code
continue
code = str(0)
if rec.parent_id:
default_padding = self.env.company.chart_account_padding
if rec.account_type == 'view':
default_padding = False
parent_code = rec.parent_id.code or ''
parent_code = int(parent_code) != 0 and str(parent_code) or ''
siblings = self.search([
('parent_id', '=', rec.parent_id.id),
('id', '!=', rec.id)
])
max_siblings_code = False
if siblings:
sibling_codes = [int(s.code) for s in siblings if s.code and s.code.isdigit()]
if sibling_codes:
max_siblings_code = max(sibling_codes)
if not max_siblings_code:
code = parent_code + str(1).zfill(default_padding or 0)
else:
code = str(max_siblings_code + 1)
rec.auto_code = code
else:
rec.auto_code = rec.code or '0'
@api.model
def search_panel_select_range(self, field_name, **kwargs):
if field_name != 'parent_id':
return super().search_panel_select_range(field_name, **kwargs)
enable_counters = kwargs.get('enable_counters', False)
search_domain = kwargs.get('search_domain', [])
all_view_accounts = self.search([('account_type', '=', 'view')], order='code')
count_by_parent = {}
if enable_counters:
all_accounts = self.search(search_domain)
for account in all_accounts:
if account.parent_id:
parent_id = account.parent_id.id
count_by_parent[parent_id] = count_by_parent.get(parent_id, 0) + 1
ancestor = account.parent_id.parent_id
while ancestor:
count_by_parent[ancestor.id] = count_by_parent.get(ancestor.id, 0) + 1
ancestor = ancestor.parent_id
values = []
for parent in all_view_accounts:
value = {
'id': parent.id,
'display_name': f"{parent.code} {parent.name}" if parent.code else parent.name,
'parent_id': parent.parent_id.id if parent.parent_id else False,
}
if enable_counters:
value['__count'] = count_by_parent.get(parent.id, 0)
values.append(value)
result = {
'parent_field': 'parent_id',
'values': values,
}
return result

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class AccountJournal(models.Model):
_inherit = "account.journal"
@api.model
def _fill_missing_values(self, vals):
journal_type = vals.get('type')
if not journal_type:
return
company = self.env['res.company'].browse(vals['company_id']) if vals.get('company_id') else self.env.company
vals['company_id'] = company.id
random_account = self.env['account.account'].search([('company_id', '=', company.id)], limit=1)
digits = len(random_account.code) if random_account else 6
if journal_type in ('bank', 'cash'):
has_liquidity_accounts = vals.get('default_account_id')
has_payment_accounts = vals.get('payment_debit_account_id') or vals.get('payment_credit_account_id')
has_profit_account = vals.get('profit_account_id')
has_loss_account = vals.get('loss_account_id')
if journal_type == 'bank':
liquidity_account_prefix = company.bank_account_code_prefix or ''
else:
liquidity_account_prefix = company.cash_account_code_prefix or company.bank_account_code_prefix or ''
parent = self.env['account.account'].search([('code', '=', liquidity_account_prefix)], limit=1)
if not parent:
raise UserError(_("Can not find account with code (%s).") % (liquidity_account_prefix,))
vals['name'] = vals.get('name') or vals.get('bank_acc_number')
if 'code' not in vals:
vals['code'] = self.get_next_bank_cash_default_code(journal_type, company)
if not vals['code']:
raise UserError(_("Cannot generate an unused journal code. Please fill the 'Shortcode' field."))
if not has_liquidity_accounts:
default_account_code = self.env['account.account']._search_new_account_code(company, digits, liquidity_account_prefix)
default_account_vals = self._prepare_liquidity_account_vals(company, default_account_code, vals)
default_account_vals['parent_id'] = parent.id
vals['default_account_id'] = self.env['account.account'].create(default_account_vals).id
if not has_payment_accounts:
vals['payment_debit_account_id'] = self.env['account.account'].create({
'name': _("Outstanding Receipts"),
'code': self.env['account.account']._search_new_account_code(company, digits, liquidity_account_prefix),
'reconcile': True,
'account_type': 'asset_current',
'company_id': company.id,
'parent_id': parent.id,
}).id
vals['payment_credit_account_id'] = self.env['account.account'].create({
'name': _("Outstanding Payments"),
'code': self.env['account.account']._search_new_account_code(company, digits, liquidity_account_prefix),
'reconcile': True,
'account_type': 'asset_current',
'company_id': company.id,
'parent_id': parent.id,
}).id
if journal_type == 'cash' and not has_profit_account:
vals['profit_account_id'] = company.default_cash_difference_income_account_id.id
if journal_type == 'cash' and not has_loss_account:
vals['loss_account_id'] = company.default_cash_difference_expense_account_id.id
if 'refund_sequence' not in vals:
vals['refund_sequence'] = vals['type'] in ('sale', 'purchase')

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api, _
class ResCompany(models.Model):
_inherit = 'res.company'
chart_account_length = fields.Integer(string='Chart of accounts length')
chart_account_padding = fields.Integer(string='Chart of accounts Padding')
useFiexedTree = fields.Boolean(string='Use Fixed Length Chart of accounts')
automticAccountsCodes = fields.Boolean(string='Automatically Generate Accounts Codes')
parent_bank_cash_account_id = fields.Many2one('account.account')
@api.model
def setting_chart_of_accounts_action(self):
"""Called by the 'Chart of Accounts' button of the setup bar."""
company = self.env.company
company.sudo().set_onboarding_step_done('account_setup_coa_state')
if company.opening_move_posted():
return 'account.action_account_form'
company.create_op_move_if_non_existant()
view_id = self.env.ref('account.init_accounts_tree').id
domain = [
('account_type', '!=', 'equity_unaffected'),
# ('is_view_account', '=', False),
('company_id', '=', company.id)
]
return {
'type': 'ir.actions.act_window',
'name': _('Chart of Accounts'),
'res_model': 'account.account',
'view_mode': 'tree',
'limit': 99999999,
'search_view_id': self.env.ref('account.view_account_search').id,
'views': [[view_id, 'list']],
'domain': domain,
}
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
chart_account_length = fields.Integer(related='company_id.chart_account_length', readonly=False)
chart_account_padding = fields.Integer(related='company_id.chart_account_padding', readonly=False)
useFiexedTree = fields.Boolean(related='company_id.useFiexedTree', readonly=False)
automticAccountsCodes = fields.Boolean(related='company_id.automticAccountsCodes', readonly=False)
bank_account_code_prefix = fields.Char(string='Bank Prefix', related='company_id.bank_account_code_prefix', readonly=False)
cash_account_code_prefix = fields.Char(string='Cash Prefix', related='company_id.cash_account_code_prefix', readonly=False)

View File

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import account_report

View File

@ -0,0 +1,217 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class AccountReport(models.Model):
_inherit = 'account.report'
filter_show_full_hierarchy = fields.Boolean(
string="Show Full Hierarchy Filter",
default=False,
help="Enable filter to display accounts in full hierarchical structure"
)
def _init_options_show_full_hierarchy(self, options, previous_options):
if self.filter_show_full_hierarchy:
if 'filters' not in options:
options['filters'] = {}
options['filters']['show_full_hierarchy'] = True
options['show_full_hierarchy'] = previous_options.get('show_full_hierarchy', False)
@api.model
def _get_options_initializers_forced_sequence_map(self):
res = super()._get_options_initializers_forced_sequence_map()
res['_init_options_show_full_hierarchy'] = 1035
return res
class TrialBalanceCustomHandler(models.AbstractModel):
_name = 'account.trial.balance.report.handler'
_inherit = 'account.report.custom.handler'
_description = 'Trial Balance Custom Handler'
def _dynamic_lines_generator(self, report, options, all_column_groups_expression_totals, warnings=None):
if not options.get('show_full_hierarchy'):
return []
lines = []
parent_view_accounts = self.env['account.account'].search([
('parent_id', '=', False),
('account_type', '=', 'view'),
], order='code, name')
for parent in parent_view_accounts:
has_children = len(parent.child_ids) > 0
parent_line = self._get_account_line(
report,
options,
parent,
all_column_groups_expression_totals,
is_parent=has_children,
level=0
)
if parent_line:
lines.append((0, parent_line))
if parent_line.get('unfolded', False) and has_children:
child_lines = self._get_children_lines_recursive(
report,
options,
parent,
all_column_groups_expression_totals,
level=1
)
for child_line in child_lines:
lines.append((0, child_line))
orphan_accounts = self.env['account.account'].search([
('parent_id', '=', False),
('account_type', '!=', 'view'),
], order='code, name')
for orphan in orphan_accounts:
orphan_line = self._get_account_line(
report,
options,
orphan,
all_column_groups_expression_totals,
is_parent=False,
level=0
)
if orphan_line:
lines.append((0, orphan_line))
return lines
def _get_children_lines_recursive(self, report, options, parent_account, all_column_groups_expression_totals, level=1):
lines = []
children = self.env['account.account'].search([
('parent_id', '=', parent_account.id)
], order='code, name')
for child in children:
has_children = len(child.child_ids) > 0
child_line = self._get_account_line(
report,
options,
child,
all_column_groups_expression_totals,
is_parent=has_children,
level=level
)
if child_line:
lines.append(child_line)
if child_line.get('unfolded', False) and has_children:
grandchildren = self._get_children_lines_recursive(
report,
options,
child,
all_column_groups_expression_totals,
level=level + 1
)
lines.extend(grandchildren)
return lines
def _report_expand_unfoldable_line_with_groupby(self, line_dict_id, groupby, options, progress, offset, unfold_all_batch_data=None):
return {
'lines': [],
'offset_increment': 0,
'has_more': False,
}
def _get_account_line(self, report, options, account, all_column_groups_expression_totals, is_parent=False,
level=0):
columns = []
for column in options['columns']:
col_group_key = column.get('column_group_key')
expression_totals = all_column_groups_expression_totals.get(col_group_key, {})
col_value = self._compute_account_balance(account, options, column, expression_totals)
columns.append(report._build_column_dict(
col_value,
column,
options=options
))
line_id = report._get_generic_line_id('account.account', account.id)
has_children = len(account.child_ids) > 0
line = {
'id': line_id,
'name': f"{account.code} {account.name}",
'level': level + 2,
'columns': columns,
'account_id': account.id,
'caret_options': 'account.account',
}
if has_children:
line['unfoldable'] = True
line['unfolded'] = line_id in options.get('unfolded_lines', [])
line['expand_function'] = '_report_expand_unfoldable_line_with_groupby'
else:
line['unfoldable'] = False
line['unfolded'] = False
return line
def _compute_account_balance(self, account, options, column, expression_totals):
if account.account_type == 'view':
children = self.env['account.account'].search([
('parent_path', '=like', f'{account.parent_path}%'),
('id', '!=', account.id),
('account_type', '!=', 'view')
])
total = 0
for child in children:
child_balance = self._get_actual_balance(child, options, column)
total += child_balance
return total
else:
return self._get_actual_balance(account, options, column)
def _get_actual_balance(self, account, options, column):
domain = [
('account_id', '=', account.id),
('parent_state', '=', 'posted'),
]
if options.get('date'):
date_from = options['date'].get('date_from')
date_to = options['date'].get('date_to')
if date_from:
domain.append(('date', '>=', date_from))
if date_to:
domain.append(('date', '<=', date_to))
aml_results = self.env['account.move.line'].read_group(
domain,
['debit:sum', 'credit:sum', 'balance:sum'],
[]
)
if aml_results:
expr_label = column.get('expression_label', 'balance')
return aml_results[0].get(expr_label, 0)
return 0

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="account_account_comp_rule" model="ir.rule">
<field name="name">Account multi-company</field>
<field name="model_id" ref="account.model_account_account"/>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_account_user,account.account.user,account.model_account_account,account.group_account_user,1,1,1,1
access_account_account_manager,account.account.manager,account.model_account_account,account.group_account_manager,1,1,1,1
access_account_account_invoice,account.account.invoice,account.model_account_account,account.group_account_invoice,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_account_user account.account.user account.model_account_account account.group_account_user 1 1 1 1
3 access_account_account_manager account.account.manager account.model_account_account account.group_account_manager 1 1 1 1
4 access_account_account_invoice account.account.invoice account.model_account_account account.group_account_invoice 1 0 0 0

View File

@ -0,0 +1,62 @@
/** @odoo-module **/
import { patch } from "@web/core/utils/patch";
import { AccountReportController } from "@odex30_account_reports/components/account_report/controller";
patch(AccountReportController.prototype, {
async unfoldLine(lineIndex) {
const targetLine = this.lines[lineIndex];
if (this.options.show_full_hierarchy && targetLine.expand_function === '_report_expand_unfoldable_line_with_groupby') {
const isCurrentlyUnfolded = targetLine.unfolded;
if (isCurrentlyUnfolded) {
this.options.unfolded_lines = this.options.unfolded_lines.filter(
id => id !== targetLine.id
);
} else {
if (!this.options.unfolded_lines.includes(targetLine.id)) {
this.options.unfolded_lines.push(targetLine.id);
}
}
this.saveSessionOptions(this.options);
this.incrementCallNumber();
await this.reload(null, this.options);
return;
}
return super.unfoldLine(...arguments);
},
foldLine(lineIndex) {
const targetLine = this.lines[lineIndex];
if (this.options.show_full_hierarchy && targetLine.expand_function === '_report_expand_unfoldable_line_with_groupby') {
this.options.unfolded_lines = this.options.unfolded_lines.filter(
id => id !== targetLine.id
);
this.saveSessionOptions(this.options);
this.incrementCallNumber();
this.reload(null, this.options);
return; // إيقاف السلوك الافتراضي
}
return super.foldLine(...arguments);
}
});

View File

@ -0,0 +1,25 @@
/** @odoo-module **/
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { AccountTypeSelection } from "@account/components/account_type_selection/account_type_selection";
import { patch } from "@web/core/utils/patch";
patch(AccountTypeSelection.prototype, {
get hierarchyOptions() {
const opts = this.options;
return [
{ name: _t('Balance Sheet') },
{ name: _t('Assets'), children: opts.filter(x => x[0] && x[0].startsWith('asset')) },
{ name: _t('Liabilities'), children: opts.filter(x => x[0] && x[0].startsWith('liability')) },
{ name: _t('Equity'), children: opts.filter(x => x[0] && x[0].startsWith('equity')) },
{ name: _t('Profit & Loss') },
{ name: _t('Income'), children: opts.filter(x => x[0] && x[0].startsWith('income')) },
{ name: _t('Expense'), children: opts.filter(x => x[0] && x[0].startsWith('expense')) },
{
name: _t('Other'),
children: opts.filter(x => x[0] && (x[0] === 'off_balance' || x[0] === 'view'))
},
];
}
});

View File

@ -0,0 +1,15 @@
/** @odoo-module **/
import { patch } from "@web/core/utils/patch";
import { AccountReportFilters } from "@odex30_account_reports/components/account_report/filters/filters";
patch(AccountReportFilters.prototype, {
async toggleFullHierarchy() {
const newValue = !this.controller.options.show_full_hierarchy;
await this.controller.updateOption('show_full_hierarchy', newValue);
this.controller.saveSessionOptions(this.controller.options);
await this.applyFilters('show_full_hierarchy');
}
});

View File

@ -0,0 +1,39 @@
.o_search_panel.account_account {
.o_search_panel_field.parent_id {
.o_search_panel_category_value {
.o_toggle_fold {
margin-right: 15px;
cursor: pointer;
}
header {
display: flex;
align-items: center;
padding: 3px 8px;
&:hover {
color: #f0f0f0;
}
.o_search_panel_label_title {
flex: 1;
}
.badge {
margin-left: auto;
font-size: 0.8em;
}
}
// Levels
&[data-level="0"] {
font-weight: bold;
}
&[data-level="1"] header { padding-left: 20px; }
&[data-level="2"] header { padding-left: 35px; }
&[data-level="3"] header { padding-left: 50px; }
&[data-level="4"] header { padding-left: 65px; }
}
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="account_chart_of_accounts.AccountReportFiltersExtension"
t-inherit="odex30_account_reports.AccountReportFiltersCustomizable"
t-inherit-mode="extension">
<xpath expr="//div[@id='filter_extra_options']" position="after">
<t t-if="controller.options and controller.options.filters and controller.options.filters.show_full_hierarchy">
<div id="filter_full_hierarchy">
<button
class="btn"
t-att-class="controller.options.show_full_hierarchy ? 'btn-primary' : 'btn-secondary'"
t-on-click="() => this.toggleFullHierarchy()">
<i class="fa fa-sitemap me-1"/>
Full Hierarchy
</button>
</div>
</t>
</xpath>
</t>
</templates>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_account_form_inherit_hierarchy" model="ir.ui.view">
<field name="name">account.account.form.inherit.hierarchy</field>
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_form"/>
<field name="arch" type="xml">
<field name="account_type" position="after">
<field name="parent_id" context="{'show_view':True}"/>
<field name="level" required="1" readonly="0"/>
<field name="automticAccountsCodes" invisible="1"/>
<field name="auto_code" invisible="1"/>
</field>
<xpath expr="//div[contains(@class, 'col-md-auto')][label[@for='code']]" position="replace">
<div class="col col-md-auto">
<label for="code" string="Code"/>
<div class="d-flex align-items-center">
<field name="automticAccountsCodes" invisible="1"/>
<field name="code"
placeholder="e.g. 101000"
class="oe_inline"
readonly="automticAccountsCodes"
force_save="1"
style="width: auto;"/>
<span class="badge text-bg-success ms-2"
invisible="not automticAccountsCodes"
title="Code is auto-generated">
Auto
</span>
</div>
</div>
</xpath>
</field>
</record>
<!-- <record id="view_account_form" model="ir.ui.view">-->
<!-- <field name="name">account.account.form</field>-->
<!-- <field name="model">account.account</field>-->
<!-- <field name="inherit_id" ref="account.view_account_form"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <field name="account_type" position="after">-->
<!-- <field name="parent_id" context="{'show_view':True}"/>-->
<!-- <field name="level" required="1" readonly="0"/>-->
<!-- <field name="automticAccountsCodes" invisible="1"/>-->
<!-- <field name="auto_code" invisible="1"/>-->
<!-- </field>-->
<!-- <div class="oe_inline oe_edit_only" position="replace">-->
<!-- <h1 class="oe_inline oe_edit_only">-->
<!-- <field name="code" placeholder="code" force_save="1"-->
<!-- attrs="{'readonly':[('automticAccountsCodes','=',True)]}"/> - -->
<!-- <field name="name" placeholder="name"/>-->
<!-- </h1>-->
<!-- </div>-->
<!-- </field>-->
<!-- </record>-->
<record id="view_account_tree_inherit" model="ir.ui.view">
<field name="name">account.account.tree.inherit</field>
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_list"/>
<field name="arch" type="xml">
<field name="code" position="after">
<field name="parent_id" optional="hide"/>
</field>
</field>
</record>
<record id="view_account_search_inherit" model="ir.ui.view">
<field name="name">account.account.search.inherit</field>
<field name="model">account.account</field>
<field name="inherit_id" ref="account.view_account_search"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="account_type"/>
<field name="level"/>
<field name="parent_id"/>
</field>
<xpath expr="//searchpanel/field[@name='root_id']" position="replace">
<field name="parent_id"
string="Hierarchical Chart"
icon="fa-sitemap"
enable_counters="1"
expand="1"
hierarchize="1"/>
</xpath>
</field>
</record>
<!-- <record id="account_report_form_inherit_hierarchy" model="ir.ui.view">-->
<!-- <field name="name">account.report.form.inherit.hierarchy</field>-->
<!-- <field name="model">account.report</field>-->
<!-- <field name="inherit_id" ref="odex30_account_reports.account_report_form"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//field[@name='root_report_id']" position="after">-->
<!-- <field name="filter_show_full_hierarchy"/>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<!--<record id="odex30_account_reports.trial_balance_report" model="account.report">-->
<!-- <field name="filter_full_hierarchy" eval="True"/>-->
<!--</record>-->
</odoo>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form_inherit" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//block[@name='fiscal_localization_setting_container']" position="after">
<block title="Chart of Accounts Hierarchy" name="chart_of_accounts_hierarchy_setting_container">
<div class="row mt16 o_settings_container">
<setting id="use_auto_account_codes"
string="Auto Generate Account Codes">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="automticAccountsCodes"/>
</div>
<div class="o_setting_right_pane">
<label for="automticAccountsCodes"/>
<div class="text-muted">
Automatically generate account codes based on parent account
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="useFiexedTree"/>
</div>
<div class="o_setting_right_pane">
<label for="useFiexedTree"/>
<div class="text-muted">
Use fixed length chart of accounts structure
</div>
<div class="content-group" invisible="not useFiexedTree">
<div class="row mt16">
<label for="chart_account_length" class="col-lg-3 o_light_label"/>
<field name="chart_account_length"/>
</div>
</div>
</div>
</div>
</setting>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label for="chart_account_padding" string="Account Code Padding"/>
<div class="text-muted">
Number of digits for account code padding
</div>
<field name="chart_account_padding" class="mt8"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label for="bank_account_code_prefix" string="Bank Account Prefix"/>
<div class="text-muted">
Prefix for bank account codes
</div>
<field name="bank_account_code_prefix" class="mt8"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label for="cash_account_code_prefix" string="Cash Account Prefix"/>
<div class="text-muted">
Prefix for cash account codes
</div>
<field name="cash_account_code_prefix" class="mt8"/>
</div>
</div>
</div>
</block>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (odoo_14) (3)" project-jdk-type="Python SDK" />
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/exp_asset_base.iml" filepath="$PROJECT_DIR$/.idea/exp_asset_base.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="f60ef796-8864-4ed6-b92d-868b4516241f" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 7
}]]></component>
<component name="ProjectId" id="2Wwmia3C9ZbGOYejadkYoVNM2s0" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="f60ef796-8864-4ed6-b92d-868b4516241f" name="Changes" comment="" />
<created>1697652146581</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1697652146581</updated>
</task>
<servers />
</component>
</project>

View File

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from . import models
from . import reports

View File

@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Asset Extend',
'summary': 'Adding new features to asset',
'description': '''
Adding the following Features:
==============================
Alter asset Form
Alter Asset category Form
Alter Product Form
Add asset operations (Transfer, Sell/Dispose, Maitenenace, Assesment)
''',
'version': '1.0.0',
'category': 'Odex30-Accounting/Odex30-Accounting',
'author': 'Expert Co. Ltd.',
'website': 'http://www.exp-sa.com',
'license': 'AGPL-3',
'application': False,
'installable': True,
'depends': [
'odex30_account_asset',
'hr', 'barcodes', 'report_xlsx'
],
'data': [
'security/groups.xml',
'security/ir.model.access.csv',
'data/asset_data.xml',
'data/asset_cron.xml',
'reports/reports.xml',
'reports/asset_barcode_pdf_report.xml',
'reports/asset_barcode_zpl_report.xml',
'views/account_asset_view.xml',
'views/account_asset_adjustment_view.xml',
'views/menus.xml',
# 'views/asset_modify_views.xml',
# 'views/asset_pause_views.xml',
# 'views/asset_sell_views.xml',
],
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding='UTF-8'?>
<odoo>
<record model="ir.cron" id="asset_cron">
<field name="name">Asset Reminder</field>
<field name="model_id" ref="model_account_asset"/>
<field name="state">code</field>
<field name="code">model._asset_cron()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
</record>
</odoo>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="asset_sequence" model="ir.sequence">
<field name="name">Asset Sequence</field>
<field name="code">asset.seq</field>
<field name="prefix">ASS/%(range_year)s/</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="True" name="use_date_range"/>
<field eval="False" name="company_id"/>
<field name="padding">6</field>
</record>
<!--record id="asset_operation_sequence" model="ir.sequence">
<field name="name">Asset Operation Sequence</field>
<field name="code">asset.operation.seq</field>
<field name="prefix">ASS OP/%(range_year)s/</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="True" name="use_date_range"/>
<field eval="False" name="company_id"/>
<field name="padding">6</field>
</record>
<record id="asset_multi_operation_sequence" model="ir.sequence">
<field name="name">Asset Multi Operation Sequence</field>
<field name="code">asset.multi.operation.seq</field>
<field name="prefix">ASS MOP/%(range_year)s/</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="True" name="use_date_range"/>
<field eval="False" name="company_id"/>
<field name="padding">6</field>
</record-->
<record id="asset_state" model="asset.state2">
<field name="name">Good</field>
</record>
<record id="asset_state2" model="asset.state2">
<field name="name">Scarp</field>
</record>
</data>
</odoo>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,912 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * exp_asset_custody
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-10-15 06:13+0000\n"
"PO-Revision-Date: 2023-10-15 06:13+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__asset_operation_count
msgid "# Done Operations"
msgstr "العمليات المعتمدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction
msgid "Action Needed"
msgstr "إجراء مطلوب"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_ids
msgid "Activities"
msgstr "الأنشطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr "زخرفة استثناء النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_state
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_state
msgid "Activity State"
msgstr "حالة النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_icon
msgid "Activity Type Icon"
msgstr "أيقونة نوع النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__amount
msgid "Amount"
msgstr "المبلغ"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset"
msgstr "الأصل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset Account"
msgstr "حساب الأصل"
#. module: exp_asset_custody
#: model:ir.actions.report,name:exp_asset_custody.action_asset_adjustment_report
#: model:ir.model,name:exp_asset_custody.model_account_asset_adjustment
msgid "Asset Adjustment"
msgstr "جرد الأصول"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset_multi_operation
msgid "Asset Multi Operation"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset_operation
msgid "Asset Operation"
msgstr ""
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset.py:0
#, python-format
msgid "Asset Operations"
msgstr "عمليات الأصول"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset Operations in done state"
msgstr "العمليات المعتمدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_status
msgid "Asset Status"
msgstr "حالة العهد"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_operation.py:0
#, python-format
msgid "Asset is required to confirm this operation."
msgstr ""
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset
msgid "Asset/Revenue Recognition"
msgstr "إثبات الأصل/الربح"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Assets Adjustment Report"
msgstr "تقرير جرد الأصول"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_assignment
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
msgid "Assets Assignment"
msgstr "إسناد عهدة"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_release
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
msgid "Assets Release"
msgstr "إرجاع عهدة"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_transfer
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Assets Transfer"
msgstr "نقل العهدة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__assigned
msgid "Assigned"
msgstr "مسند"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__assignment
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__assignment
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_assignment
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_assignment
msgid "Assignment"
msgstr "أسناد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Assignment Info"
msgstr "معلومات الإسناد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.hr_Employee_form_inherit0
msgid "Assignments"
msgstr "العهد العينية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_attachment_count
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_attachment_count
msgid "Attachment Count"
msgstr "عدد المرفقات"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__barcode
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__barcode
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Barcode"
msgstr "باركود"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned
msgid "Barcode Scanned"
msgstr "باركود"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Barcode..."
msgstr "الباركود..."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__department
msgid "By Department"
msgstr "الإدارة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__employee
msgid "By Employee"
msgstr "الموظف"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__location
msgid "By Location"
msgstr "الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__cancel
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__cancel
msgid "Cancel"
msgstr "إلغاء"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Confirm"
msgstr "تأكيد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_uid
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_uid
msgid "Created by"
msgstr "أنشئ بواسطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_date
msgid "Created on"
msgstr "أنشئ في"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Current"
msgstr "الحالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__department_id
msgid "Current Department"
msgstr "الإدارة الحالية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__employee_id
msgid "Current Employee"
msgstr "الموظف الحالي"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Current Info"
msgstr "المعلومات الحالية"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form
msgid "Custody Info"
msgstr "معلومات العهدة"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_operation_main
msgid "Custody Operations"
msgstr "عمليات الأصول"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_period
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_period
msgid "Custody Period"
msgstr "فترة العهدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_type
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Custody Type"
msgstr "نوع العهدة"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_custody_operation
msgid "Custody operations"
msgstr "عمليات العهد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__date
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Date"
msgstr "التاريخ"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Date:"
msgstr "التاريخ:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_department_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Department"
msgstr "الإدارة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Description:"
msgstr "الوصف:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_hr_employee__display_name
msgid "Display Name"
msgstr "الاسم المعروض"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__done
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__done
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Done"
msgstr "المنتهية"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__draft
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__draft
msgid "Draft"
msgstr "مسودة"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_hr_employee
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_employee_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Employee"
msgstr "الموظف"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_follower_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_follower_ids
msgid "Followers"
msgstr "المتابعون"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_channel_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_channel_ids
msgid "Followers (Channels)"
msgstr "المتابعون (القنوات)"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_partner_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_partner_ids
msgid "Followers (Partners)"
msgstr "المتابعون (الشركاء)"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__general
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__general
msgid "General"
msgstr "عام"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__good
msgid "Good"
msgstr "جيد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Group By..."
msgstr "تجميع بـ..."
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_hr_employee__id
msgid "ID"
msgstr "المُعرف"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_icon
msgid "Icon"
msgstr "الأيقونة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr "الأيقونة للإشارة إلى استثناء النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread
msgid "If checked, new messages require your attention."
msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها."
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__in_progress
msgid "In Progress"
msgstr "جاري"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_is_follower
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_is_follower
msgid "Is Follower"
msgstr "متابع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_hr_employee____last_update
msgid "Last Modified on"
msgstr "آخر تعديل في"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_uid
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_uid
msgid "Last Updated by"
msgstr "آخر تحديث بواسطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_date
msgid "Last Updated on"
msgstr "آخر تحديث في"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_location_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Location"
msgstr "الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_main_attachment_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_main_attachment_id
msgid "Main Attachment"
msgstr "المرفقات"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose an asset in all operation line."
msgstr ""
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose custody period for all operation lines."
msgstr "الرجاء التاكد من إدخال فترة العهدة في جميع العمليات."
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose custody type for all operation lines."
msgstr "الرجاء التاكد من إدخال نوع العهدة في جميع العمليات."
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you enter the return date for all temporary custodies."
msgstr "الرجاء التاكد من إدخال تاريخ الإرجاع للعهد المؤقتة."
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__manual
msgid "Manual"
msgstr "يدوي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error
msgid "Message Delivery error"
msgstr "خطأ في تسليم الرسائل"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_ids
msgid "Messages"
msgstr "الرسائل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Missing Assets:"
msgstr "الأصول المفقودة:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__model_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Model"
msgstr "النموذج"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__multi_operation_id
msgid "Multi Operation"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_assignment
msgid "Multiple Assignment"
msgstr "إسناد العهد"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_release
msgid "Multiple Release"
msgstr "إرجاع العهد"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_transfer
msgid "Multiple Transfer"
msgstr "نقل العهد"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_multi_operation
msgid "Multiple operations"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__my_activity_date_deadline
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__my_activity_date_deadline
msgid "My Activity Deadline"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__name
msgid "Name"
msgstr "الإسم"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "New"
msgstr "جديد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Department"
msgstr "الإدارة الجديدة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Employee"
msgstr "الموظف الجديد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Location"
msgstr "الموقع الجديد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_date_deadline
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_date_deadline
msgid "Next Activity Deadline"
msgstr "الموعد النهائي للنشاط التالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_summary
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_summary
msgid "Next Activity Summary"
msgstr "ملخص النشاط التالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_id
msgid "Next Activity Type"
msgstr "نوع النشاط التالي"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "No asset found with the selected barcode"
msgstr "لم يتم العثور على أصل لهذا الباركود"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__note
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__note
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Note"
msgstr "ملاحظة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction_counter
msgid "Number of Actions"
msgstr "عدد الإجراءات"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset__asset_operation_count
msgid "Number of done asset operations"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error_counter
msgid "Number of errors"
msgstr "عدد الاخطاء"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr "عدد الرسائل التي تتطلب إجراء"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "عدد الرسائل الحادث بها خطأ في التسليم"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread_counter
msgid "Number of unread messages"
msgstr "عدد الرسائل الجديدة"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_operation.py:0
#, python-format
msgid "Only draft operations can be deleted."
msgstr "لا يمكن حذف العملية الا في الحالة مبدئية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__operation_ids
msgid "Operation"
msgstr "عملية"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_operation_analysis
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_operation_graph
msgid "Operation Analysis"
msgstr "تحليل العمليات"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form
msgid "Operations"
msgstr "العمليات"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__pending
msgid "Pending"
msgstr "معلق"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__permanent
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__permanent
msgid "Permanent"
msgstr "دائمة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__personal
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__personal
msgid "Personal"
msgstr "شخصية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_hr_employee__petty_cash_counts
msgid "Petty Cash Counts"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__product_id
msgid "Product"
msgstr "المنتج"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__purpose
msgid "Purpose"
msgstr "الغرض"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Reject"
msgstr "رفض"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__release
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__release
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_release
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_release
msgid "Release"
msgstr "إرجاع"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Release Info"
msgstr "معلومات الإرجاع"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
msgid "Release Location"
msgstr "موقع الإرجاع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__user_id
msgid "Responsible"
msgstr "المسئول"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__department_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Responsible Department"
msgstr "الإدارة المسئولة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_user_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_user_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_user_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Responsible User"
msgstr "الموظف المسئول"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__return_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__return_date
msgid "Return Date"
msgstr "تاريخ الإرجاع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_sms_error
msgid "SMS Delivery error"
msgstr "خطأ في تسليم الرسائل القصيرة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__scrap
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__scrap
msgid "Scrap"
msgstr "تالف"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Serial No"
msgstr "المتسلسل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Set to Draft"
msgstr "تعيين كمسودة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Signatures:"
msgstr ""
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Start"
msgstr "بدأ"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__state
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__state
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "State"
msgstr "الحالة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__status
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_statuso
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Status"
msgstr "الحالة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_state
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr "الأنشطة المستقبيلة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__submit
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Submit"
msgstr "إرسال"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__temporary
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__temporary
msgid "Temporary"
msgstr "مؤقتة"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset.py:0
#, python-format
msgid "The period of %s is finished %s."
msgstr "فترة %s قد إنتهت %s."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__transfer
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__transfer
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_transfer
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_transfer
msgid "Transfer"
msgstr "نقل"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__type
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Type"
msgstr "النوع"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr "نوع النشاط الاستثنائي المسجل."
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Type:"
msgstr "النوع:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread
msgid "Unread Messages"
msgstr "الرسائل الجديدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread_counter
msgid "Unread Messages Counter"
msgstr "عدد الرسائل الجديدة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned
msgid "Value of the last barcode scanned."
msgstr "قيمة آخر باركود ممسوح ضوئيًا."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__good_v
msgid "Very Good"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__website_message_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__website_message_ids
msgid "Website Messages"
msgstr "رسائل الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__website_message_ids
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__website_message_ids
msgid "Website communication history"
msgstr "سجل تواصل الموقع"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "You can not confirm operation without lines."
msgstr "لا يمكن تأكيد العملية دون إدخال التفاصيل"
#. module: exp_asset_base
#: model:ir.actions.report,name:exp_asset_base.label_barcode_account_asset
msgid "Asset Barcode (ZPL)"
msgstr "باركود الأصل (ZPL)"
#. module: exp_asset_base
#: model:ir.actions.report,print_report_name:exp_asset_base.report_account_asset_barcode
msgid "'Assets barcode - %s' % (object.name)"
msgstr "'باركود الأصول - %s' % (object.name)"
#. module: exp_asset_base
#: model:ir.actions.report,name:exp_asset_base.report_account_asset_barcode
msgid "Asset Barcode (PDF)"
msgstr "باركود الأصل (PDF)"
#. module: exp_asset_base
#: model_terms:ir.ui.view,arch_db:exp_asset_base.report_asset_barcode
msgid "<span class=\"text-muted\">No barcode available</span>"
msgstr "لا يوجد باركود متاح"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from . import account_asset
from . import account_asset_adjustment
from . import asset_modify
from . import asset_pause
from . import asset_sell

View File

@ -0,0 +1,294 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import models, fields, api, _
from datetime import datetime
from odoo.osv import expression
from dateutil.relativedelta import relativedelta
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
class AccountAssetManufacturer(models.Model):
_name = 'account.asset.manufacturer'
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = 'Asset Manufacturer'
name = fields.Char(required=True, tracking=True)
class AccountAssetLocation(models.Model):
_name = 'account.asset.location'
_inherit = ["mail.thread", "mail.activity.mixin"]
_description = 'Asset Location'
_parent_name = "parent_id"
_parent_store = True
_rec_name = 'complete_name'
_order = 'complete_name'
name = fields.Char(required=True, tracking=True)
complete_name = fields.Char('Asset Location', compute='_compute_complete_name', tracking=True, store=True , recursive=True)
code = fields.Char(required=True, tracking=True)
type = fields.Selection(selection=[('ordinary', 'Ordinary'), ('view', 'View')], default='ordinary', required=True,
tracking=True)
parent_id = fields.Many2one(string='Parent', comodel_name='account.asset.location', domain=[('type', '=', 'view')],
tracking=True)
parent_path = fields.Char(index=True, tracking=True)
child_id = fields.One2many('account.asset.location', 'parent_id', 'Child Locations', tracking=True)
@api.depends('name', 'parent_id.complete_name')
def _compute_complete_name(self):
for location in self:
if location.parent_id:
location.complete_name = '%s / %s' % (location.parent_id.complete_name, location.name)
else:
location.complete_name = location.name
class AccountAssetAsset(models.Model):
_name = 'account.asset'
_inherit = ['account.asset', "mail.thread", "mail.activity.mixin"]
asset_picture = fields.Binary(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
serial_no = fields.Char(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
model = fields.Char(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
manufacturer_id = fields.Many2one(
comodel_name='account.asset.manufacturer',
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
barcode = fields.Char(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True, index=True, copy=False,
)
note = fields.Text(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
receive_date = fields.Date(
states={'draft': [('readonly', False)]},
readonly=True,
)
service_provider_id = fields.Many2one(
comodel_name='res.partner',
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
next_maintenance_date = fields.Date(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True,
)
warranty_period = fields.Integer(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True, string="Warranty Period(Months)"
)
warranty_end_date = fields.Date(
compute='_compute_warranty_end_date',
readonly=True, store=True,
)
warranty_contract = fields.Binary(
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True, )
value_residual = fields.Monetary(
string='Depreciable Value',
compute='_compute_value_residual',
store=True)
product_id = fields.Many2one(comodel_name='product.product',
domain=[('property_account_expense_id.can_create_asset', '=', True),
('property_account_expense_id.account_type', '=', 'asset_fixed')],
states={'draft': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True, tracking=True)
responsible_dept_id = fields.Many2one(comodel_name='hr.department', string='Responsible Department',
states={'draft': [('readonly', False)], 'model': [('readonly', False)],
'unlock': [('readonly', False)]},
readonly=True,
default=lambda self: self.env.user.employee_id.department_id.id,
tracking=True)
responsible_user_id = fields.Many2one(
comodel_name='res.users',
states={'draft': [('readonly', False)], 'model': [('readonly', False)], 'unlock': [('readonly', False)]},
readonly=True, default=lambda self: self.env.user, tracking=True)
asset_adjustment_count = fields.Integer(
compute='_asset_adjustment_count',
string='# of Adjustments',
help="Number of adjustments")
status = fields.Selection(
selection=[('new', 'New'), ('available', 'Available')],
default='new', tracking=True)
location_id = fields.Many2one(comodel_name='account.asset.location', string='Current Location', tracking=True)
state = fields.Selection(selection_add=[('unlock', 'Unlock')])
limit = fields.Float(tracking=True)
_sql_constraints = [
('asset_barcode_uniq', 'unique (barcode)', 'Asset barcode must be unique.')
]
def validate(self):
"""Validate asset and set it to running state"""
self.ensure_one() # تأكد أن العملية على record واحد فقط
# تحقق من الشروط
# غيّر الحالة (tracking سيعمل تلقائياً)
self.write({'state': 'open'})
# رسالة
asset_type_labels = {
'purchase': _('Asset'),
'sale': _('Deferred revenue'),
'expense': _('Deferred expense'),
}
label = asset_type_labels.get(self.asset_type, _('Asset'))
message = _('%s has been validated and is now running.') % label
self.message_post(body=message)
return True
# يجب تحويله إلى analytic_distribution
@api.onchange('location_id')
def onchange_location_id(self):
if self.location_id and self.location_id.analytic_distribution:
self.analytic_distribution = self.location_id.analytic_distribution
# @api.onchange('location_id')
# def onchange_location_id(self):
# if self.analytic_distribution and self.location_id.account_analytic_id:
# self.analytic_distribution = self.location_id.account_analytic_id.id
# def action_asset_modify(self):
# """ Returns an action opening the asset modification wizard.
# """
# self.ensure_one()
# return {
# 'name': _('Modify Asset'),
# 'view_mode': 'form',
# 'res_model': 'account.asset.modify',
# 'type': 'ir.actions.act_window',
# 'target': 'current',
# 'context': {
# 'default_asset_id': self.id,
# },
# }
def action_asset_pause(self):
""" Returns an action opening the asset pause wizard."""
self.ensure_one()
return {
'name': _('Pause Asset'),
'view_mode': 'form',
'res_model': 'asset.pause',
'type': 'ir.actions.act_window',
'target': 'current',
'context': {
'default_asset_id': self.id,
},
}
def action_set_to_close(self):
""" Returns an action opening the asset pause wizard."""
self.ensure_one()
return {
'name': _('Sell Asset'),
'view_mode': 'form',
'res_model': 'asset.sell',
'type': 'ir.actions.act_window',
'target': 'current',
'context': {
'default_asset_id': self.id,
},
}
def act_unlock(self):
self.state = 'unlock'
def act_lock(self):
self.state = 'open'
def _asset_adjustment_count(self):
for asset in self:
asset.asset_adjustment_count = len(
self.env['account.asset.adjustment.line'].search([('asset_id', '=', asset.id)]))
def open_asset_adjustment(self):
return {
'name': _('Asset Adjustment'),
'view_mode': 'tree',
'res_model': 'account.asset.adjustment.line',
'type': 'ir.actions.act_window',
'domain': [('asset_id', '=', self.id)],
'flags': {'search_view': True, 'action_buttons': False},
}
@api.depends('acquisition_date', 'warranty_period')
def _compute_warranty_end_date(self):
for asset in self:
if asset.acquisition_date:
asset.warranty_end_date = asset.acquisition_date + relativedelta(months=asset.warranty_period)
@api.depends('name', 'barcode')
def name_get(self):
return [(r.id, r.name + (r.barcode and '-' + r.barcode or '')) for r in self]
@api.model
def name_search(self, name, args=None, operator='ilike', limit=100):
args = args or []
domain = []
if name:
domain = ['|', ('barcode', operator, name), ('name', operator, name)]
if operator in expression.NEGATIVE_TERM_OPERATORS:
domain = ['&', '!'] + domain[1:]
assets = self.search(domain + args, limit=limit)
return assets.name_get()
@api.model
def create(self, values):
if values.get('state', False) != 'model':
values['serial_no'] = self.env['ir.sequence'].with_context(
ir_sequence_date=values.get('acquisition_date', fields.Date.today())).next_by_code('asset.seq')
return super(AccountAssetAsset, self).create(values)
def action_save_model(self):
action = super(AccountAssetAsset, self).action_save_model()
action['context']['default_asset_type'] = self.asset_type
return action
@api.model
def _asset_cron(self):
today = fields.Date.today()
for asset in self.search([('next_maintenance_date', '=', today)]):
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('account_asset.model_account_asset_asset').id,
'res_id': asset.id,
'user_id': asset.responsible_user_id.id,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('The %s with barcode %s has schedule maintenance today ,please follow.') % (
asset.name, asset.barcode),
'date_deadline': asset.next_maintenance_date,
})
for asset in self.search([('warranty_end_date', '=', today)]):
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('account_asset.model_account_asset_asset').id,
'res_id': asset.id,
'user_id': asset.responsible_user_id.id,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('The warrant period of %s with barcode %s has end!') % (asset.name, asset.barcode),
'date_deadline': asset.warranty_end_date,
})
@api.onchange('model_id', 'original_value')
def _onchange_model_id(self):
super(AccountAssetAsset, self)._onchange_model_id()
if self.model_id and self.original_value <= self.model_id.limit:
self.method_number = 0

View File

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import api, fields, models, exceptions, _
from odoo.exceptions import UserError
class AccountAssetAdjustment(models.Model):
_name = 'account.asset.adjustment'
_inherit = ['barcodes.barcode_events_mixin',"mail.thread", "mail.activity.mixin"]
_description = 'Asset Adjustment'
name = fields.Char(
states={'draft': [('readonly', False)]},
readonly=True, required=True,tracking=True
)
date = fields.Date(
default=fields.Date.context_today,
index=True, copy=False, readonly=True, required=True,tracking=True,
states={'draft': [('readonly', False)]}
)
type = fields.Selection(
selection=[('product', 'By Product'),
('model', 'By Model')],
states={'draft': [('readonly', False)]},
readonly=True,tracking=True
)
product_id = fields.Many2one(
comodel_name='product.product',
domain=[('property_account_expense_id.can_create_asset', '=', True),
('property_account_expense_id.account_type', '=', 'asset_fixed')],
states={'draft': [('readonly', False)]},
readonly=True,tracking=True
)
model_id = fields.Many2one(
comodel_name='account.asset',
domain=[('asset_type', '=', 'purchase'), ('state', '=', 'model')],
states={'draft': [('readonly', False)]},
readonly=True,tracking=True
)
barcode = fields.Char(
states={'in_progress': [('readonly', False)]},
readonly=True,tracking=True
)
adjustment_line_ids = fields.One2many(
'account.asset.adjustment.line', 'adjustment_id',
states={'in_progress': [('readonly', False)]},
readonly=True,tracking=True
)
state = fields.Selection(
selection=[('draft', 'Draft'),
('in_progress', 'In Progress'),
('done', 'Done'),
('cancel', 'Cancel')],
required=True, default='draft',tracking=True
)
def build_domain(self):
return (self.type == 'product' and [('product_id', '=', self.product_id.id)]) or \
(self.type == 'model' and [('model_id', '=', self.model_id.id)]) or []
def act_progress(self):
domain = self.build_domain()
assets = self.env['account.asset'].search(domain+[('asset_type', '=', 'purchase'),
('state', '!=', 'model'), ('parent_id', '=', False)])
self.adjustment_line_ids = [(0, 0, {'asset_id': s.id}) for s in assets]
self.state = 'in_progress'
def act_done(self):
if self.adjustment_line_ids.search([('adjustment_id', '=', self.id), ('exist', '=', True), ('asset_status2', '=', False)]):
raise UserError(_('You should enter the asset status for all assets that marked as exist.'))
self.barcode = False
self.state = 'done'
def act_cancel(self):
self.state = 'cancel'
def act_draft(self):
self.state = 'draft'
self.adjustment_line_ids.unlink()
@api.onchange('type')
def onchange_type(self):
self.product_id = False
self.model_id = False
def on_barcode_scanned(self, barcode):
if barcode:
line = self.adjustment_line_ids.filtered(lambda x: x.barcode == barcode)
if not line:
raise UserError(_('No asset found with the selected barcode'))
for l in line:
l.exist = True
@api.onchange('barcode')
def onchange_barcode(self):
self.on_barcode_scanned(self.barcode)
class AccountAssetAdjustmentLine(models.Model):
_name = 'account.asset.adjustment.line'
_description = 'Asset Adjustment Line'
adjustment_id = fields.Many2one(comodel_name='account.asset.adjustment',tracking=True)
asset_id = fields.Many2one(comodel_name='account.asset',tracking=True)
barcode = fields.Char(related='asset_id.barcode',tracking=True)
serial_no = fields.Char(related='asset_id.serial_no',tracking=True)
asset_status = fields.Selection(selection=[('good', 'Good'), ('scrap', 'Scrap')],tracking=True)
asset_status2 = fields.Many2one(
comodel_name='asset.state2',
string='Asset Status',tracking=True)
exist = fields.Boolean(string="Exist?",tracking=True)
class AccountAssestatus(models.Model):
_name = 'asset.state2'
name = fields.Char(string='Name')
#

View File

@ -0,0 +1,179 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class AssetModify(models.Model):
_name = 'account.asset.modify'
_description = 'Modify Asset'
_inherit = ['mail.thread', 'mail.activity.mixin']
name = fields.Text(string='Reason',tracking=True)
asset_id = fields.Many2one(string="Asset", comodel_name='account.asset', domain="[('asset_type', '=', 'purchase'), ('state', '!=', 'model'), ('parent_id', '=', False)]",required=True, help="The asset to be modified by this wizard", ondelete="cascade",tracking=True)
method_number = fields.Integer(string='Number of Depreciations', required=True,tracking=True)
method_period = fields.Selection([('1', 'Months'), ('12', 'Years')], string='Number of Months in a Period', help="The amount of time between two depreciations",tracking=True)
value_residual = fields.Monetary(string="Depreciable Amount", help="New residual amount for the asset",tracking=True)
salvage_value = fields.Monetary(string="Not Depreciable Amount", help="New salvage amount for the asset",tracking=True)
currency_id = fields.Many2one(related='asset_id.currency_id')
date = fields.Date(default=fields.Date.today(), string='Date',tracking=True)
need_date = fields.Boolean(compute="_compute_need_date")
gain_value = fields.Boolean(compute="_compute_gain_value", help="Technical field to know if we should display the fields for the creation of gross increase asset")
account_asset_id = fields.Many2one('account.account', string="Asset Gross Increase Account",tracking=True)
account_asset_counterpart_id = fields.Many2one('account.account',tracking=True)
account_depreciation_id = fields.Many2one('account.account',tracking=True)
account_depreciation_expense_id = fields.Many2one('account.account',tracking=True)
state = fields.Selection(selection=[('draft', 'Draft'),('confirm', 'Confirmed'),('approve', 'Approved'),('done', 'Done')],default='draft',readonly=True,tracking=True)
@api.model
def create(self, vals):
if 'asset_id' in vals:
asset = self.env['account.asset'].browse(vals['asset_id'])
if asset.depreciation_move_ids.filtered(lambda m: m.state == 'posted' and not m.reversal_move_id and m.date > fields.Date.today()):
raise UserError(_('Reverse the depreciation entries posted in the future in order to modify the depreciation'))
if 'method_number' not in vals:
vals.update({'method_number': len(asset.depreciation_move_ids.filtered(lambda move: move.state != 'posted')) or 1})
if 'method_period' not in vals:
vals.update({'method_period': asset.method_period})
if 'salvage_value' not in vals:
vals.update({'salvage_value': asset.salvage_value})
if 'value_residual' not in vals:
vals.update({'value_residual': asset.value_residual})
if 'account_asset_id' not in vals:
vals.update({'account_asset_id': asset.account_asset_id.id})
if 'account_depreciation_id' not in vals:
vals.update({'account_depreciation_id': asset.account_depreciation_id.id})
if 'account_depreciation_expense_id' not in vals:
vals.update({'account_depreciation_expense_id': asset.account_depreciation_expense_id.id})
return super(AssetModify, self).create(vals)
def act_confirm(self):
self.state = 'confirm'
def act_approve(self):
self.state = 'approve'
def act_draft(self):
self.state = 'draft'
def modify(self):
""" Modifies the duration of asset for calculating depreciation
and maintains the history of old values, in the chatter.
"""
old_values = {
'method_number': self.asset_id.method_number,
'method_period': self.asset_id.method_period,
'value_residual': self.asset_id.value_residual,
'salvage_value': self.asset_id.salvage_value,
}
asset_vals = {
'method_number': self.method_number,
'method_period': self.method_period,
'value_residual': self.value_residual,
'salvage_value': self.salvage_value,
}
if self.need_date:
asset_vals.update({
'prorata_date': self.date,
})
if self.env.context.get('resume_after_pause'):
asset_vals.update({'state': 'open'})
self.asset_id.message_post(body=_("Asset unpaused"))
else:
self = self.with_context(ignore_prorata=True)
current_asset_book = self.asset_id.value_residual + self.asset_id.salvage_value
after_asset_book = self.value_residual + self.salvage_value
increase = after_asset_book - current_asset_book
new_residual = min(current_asset_book - min(self.salvage_value, self.asset_id.salvage_value), self.value_residual)
new_salvage = min(current_asset_book - new_residual, self.salvage_value)
residual_increase = max(0, self.value_residual - new_residual)
salvage_increase = max(0, self.salvage_value - new_salvage)
if residual_increase or salvage_increase:
move = self.env['account.move'].create({
'journal_id': self.asset_id.journal_id.id,
'date': fields.Date.today(),
'line_ids': [
(0, 0, {
'account_id': self.account_asset_id.id,
'debit': residual_increase + salvage_increase,
'credit': 0,
'name': _('Value increase for: %(asset)s', asset=self.asset_id.name),
}),
(0, 0, {
'account_id': self.account_asset_counterpart_id.id,
'debit': 0,
'credit': residual_increase + salvage_increase,
'name': _('Value increase for: %(asset)s', asset=self.asset_id.name),
}),
],
})
move.action_post()
asset_increase = self.env['account.asset'].create({
'name': self.asset_id.name + ': ' + self.name,
'currency_id': self.asset_id.currency_id.id,
'company_id': self.asset_id.company_id.id,
'asset_type': self.asset_id.asset_type,
'method': self.asset_id.method,
'method_number': self.method_number,
'method_period': self.method_period,
'acquisition_date': self.date,
'value_residual': residual_increase,
'salvage_value': salvage_increase,
'original_value': residual_increase + salvage_increase,
'account_asset_id': self.account_asset_id.id,
'account_depreciation_id': self.account_depreciation_id.id,
'account_depreciation_expense_id': self.account_depreciation_expense_id.id,
'journal_id': self.asset_id.journal_id.id,
'parent_id': self.asset_id.id,
'original_move_line_ids': [(6, 0, move.line_ids.filtered(lambda r: r.account_id == self.account_asset_id).ids)],
})
asset_increase.validate()
subject = _('A gross increase has been created') + ': <a href=# data-oe-model=account.asset data-oe-id=%d>%s</a>' % (asset_increase.id, asset_increase.name)
self.asset_id.message_post(body=subject)
if increase < 0:
if self.env['account.move'].search([('asset_id', '=', self.asset_id.id), ('state', '=', 'draft'), ('date', '<=', self.date)]):
raise UserError('There are unposted depreciations prior to the selected operation date, please deal with them first.')
move = self.env['account.move'].create(self.env['account.move']._prepare_move_for_asset_depreciation({
'amount': -increase,
'asset_id': self.asset_id,
'move_ref': _('Value decrease for: %(asset)s', asset=self.asset_id.name),
'date': self.date,
'asset_remaining_value': 0,
'asset_depreciated_value': 0,
'asset_value_change': True,
})).action_post()
asset_vals.update({
'value_residual': new_residual,
'salvage_value': new_salvage,
})
self.asset_id.write(asset_vals)
self.asset_id.compute_depreciation_board()
self.asset_id.children_ids.write({
'method_number': asset_vals['method_number'],
'method_period': asset_vals['method_period'],
})
for child in self.asset_id.children_ids:
child.compute_depreciation_board()
tracked_fields = self.env['account.asset'].fields_get(old_values.keys())
changes, tracking_value_ids = self.asset_id._message_track(tracked_fields, old_values)
if changes:
self.asset_id.message_post(body=_('Depreciation board modified') + '<br>' + self.name, tracking_value_ids=tracking_value_ids)
return self.write({'state':'done'})
@api.depends('asset_id', 'value_residual', 'salvage_value')
def _compute_need_date(self):
for record in self:
value_changed = record.value_residual + record.salvage_value != record.asset_id.value_residual + record.asset_id.salvage_value
record.need_date = (self.env.context.get('resume_after_pause') and record.asset_id.prorata) or value_changed
@api.depends('asset_id', 'value_residual', 'salvage_value')
def _compute_gain_value(self):
for record in self:
record.gain_value = record.value_residual + record.salvage_value > record.asset_id.value_residual + record.asset_id.salvage_value

View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
class AssetPause(models.Model):
_name = 'asset.pause'
_description = 'Pause Asset'
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'asset_id'
date = fields.Date(string='Pause date', required=True, default=fields.Date.today(),tracking=True)
asset_id = fields.Many2one('account.asset', domain="[('asset_type', '=', 'purchase'), ('state', '!=', 'model'), ('parent_id', '=', False)]",required=True,tracking=True)
state = fields.Selection(selection=[('draft', 'Draft'),('confirm', 'Confirmed'),('approve', 'Approved'),('done', 'Done')],default='draft',readonly=True,tracking=True)
def act_confirm(self):
self.state = 'confirm'
def act_approve(self):
self.state = 'approve'
def act_draft(self):
self.state = 'draft'
def do_action(self):
for record in self:
record.asset_id.pause(pause_date=record.date)
return self.write({'state':'done'})

View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
class AssetSell(models.Model):
_name = 'asset.sell'
_description = 'Sell Asset'
_inherit = ['mail.thread', 'mail.activity.mixin']
_rec_name = 'asset_id'
asset_id = fields.Many2one('account.asset', domain="[('asset_type', '=', 'purchase'), ('state', '!=', 'model'), ('parent_id', '=', False)]",required=True,tracking=True)
company_id = fields.Many2one('res.company', default=lambda self: self.env.company)
action = fields.Selection([('sell', 'Sell'), ('dispose', 'Dispose')], required=True, default='sell',tracking=True)
invoice_id = fields.Many2one('account.move', string="Customer Invoice", help="The disposal invoice is needed in order to generate the closing journal entry.", domain="[('move_type', '=', 'out_invoice'), ('state', '=', 'posted')]",tracking=True)
invoice_line_id = fields.Many2one('account.move.line', help="There are multiple lines that could be the related to this asset", domain="[('move_id', '=', invoice_id), ('exclude_from_invoice_tab', '=', False)]",tracking=True)
select_invoice_line_id = fields.Boolean(compute="_compute_select_invoice_line_id")
gain_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', company_id),('type','!=','view')]", related='company_id.gain_account_id', help="Account used to write the journal item in case of gain", readonly=False,tracking=True)
loss_account_id = fields.Many2one('account.account', domain="[('deprecated', '=', False), ('company_id', '=', company_id)]", related='company_id.loss_account_id', help="Account used to write the journal item in case of loss", readonly=False,tracking=True)
gain_or_loss = fields.Selection([('gain', 'Gain'), ('loss', 'Loss'), ('no', 'No')], compute='_compute_gain_or_loss', help="Technical field to know is there was a gain or a loss in the selling of the asset",tracking=True)
state = fields.Selection(selection=[('draft', 'Draft'),('confirm', 'Confirmed'),('approve', 'Approved'),('done', 'Done')],default='draft',readonly=True,tracking=True)
def act_confirm(self):
self.state = 'confirm'
def act_approve(self):
self.state = 'approve'
def act_draft(self):
self.state = 'draft'
@api.depends('invoice_id', 'action')
def _compute_select_invoice_line_id(self):
for record in self:
record.select_invoice_line_id = record.action == 'sell' and len(record.invoice_id.invoice_line_ids) > 1
@api.onchange('action')
def _onchange_action(self):
if self.action == 'sell' and self.asset_id.children_ids.filtered(lambda a: a.state in ('draft', 'open') or a.value_residual > 0):
raise UserError(_("You cannot automate the journal entry for an asset that has a running gross increase. Please use 'Dispose' on the increase(s)."))
@api.depends('asset_id', 'invoice_id', 'invoice_line_id')
def _compute_gain_or_loss(self):
for record in self:
line = record.invoice_line_id or len(record.invoice_id.invoice_line_ids) == 1 and record.invoice_id.invoice_line_ids or self.env['account.move.line']
if record.asset_id.value_residual < abs(line.balance):
record.gain_or_loss = 'gain'
elif record.asset_id.value_residual > abs(line.balance):
record.gain_or_loss = 'loss'
else:
record.gain_or_loss = 'no'
def do_action(self):
self.ensure_one()
invoice_line = self.env['account.move.line'] if self.action == 'dispose' else self.invoice_line_id or self.invoice_id.invoice_line_ids
return self.asset_id.set_to_close(invoice_line_id=invoice_line, date=invoice_line.move_id.invoice_date)

View File

@ -0,0 +1,4 @@
from . import abstract_report_xlsx
from . import asset_register_report_xlsx
#from . import asset_depreciation_report_xlsx
#from . import asset_register_report

View File

@ -0,0 +1,688 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models
class AbstractReportXslx(models.AbstractModel):
_name = 'report.asset_abstract_report_xlsx'
_inherit = 'report.report_xlsx.abstract'
_description = 'asset_abstract_report_xlsx'
def get_workbook_options(self):
vals = super(AbstractReportXslx, self).get_workbook_options()
vals.update({"constant_memory": True})
return vals
def generate_xlsx_report(self, workbook, data, objects):
# Initialize report variables
report_data = {
"workbook": None,
"sheet": None, # main sheet which will contains report
"columns": None, # columns of the report
"row_pos": None, # row_pos must be incremented at each writing lines
"formats": None,
}
self._define_formats(workbook, report_data)
# Get report data
report_name = self._get_report_name(objects, data=data)
report_footer = self._get_report_footer()
filters = self._get_report_filters(objects)
report_data["columns"] = self._get_report_columns(objects)
report_data["workbook"] = workbook
report_data["sheet"] = workbook.add_worksheet(report_name[:31])
self._set_column_width(report_data)
# Fill report
report_data["row_pos"] = 0
self._write_report_title(report_name, report_data)
self._write_filters(filters, report_data)
self._generate_report_content(workbook, objects, data, report_data)
self._write_report_footer(report_footer, report_data)
def _define_formats(self, workbook, report_data):
"""Add cell formats to current workbook.
Those formats can be used on all cell.
Available formats are :
* format_bold
* format_right
* format_right_bold_italic
* format_header_left
* format_header_center
* format_header_right
* format_header_amount
* format_amount
* format_percent_bold_italic
"""
currency_id = self.env["res.company"]._default_currency_id()
report_data["formats"] = {
"format_bold": workbook.add_format({"bold": True}),
"format_right": workbook.add_format({"align": "right"}),
"format_left": workbook.add_format({"align": "left"}),
"format_center": workbook.add_format({'align': 'center'}),
"format_right_bold_italic": workbook.add_format(
{"align": "right", "bold": True, "italic": True}
),
"format_header_left": workbook.add_format(
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
),
"format_header_center": workbook.add_format(
{"bold": True, "align": "center", "border": True, "bg_color": "#FFFFCC"}
),
"format_header_right": workbook.add_format(
{"bold": True, "align": "right", "border": True, "bg_color": "#FFFFCC"}
),
"format_header_amount": workbook.add_format(
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
).set_num_format("#,##0." + "0" * currency_id.decimal_places),
"format_amount": workbook.add_format().set_num_format(
"#,##0." + "0" * currency_id.decimal_places
),
"format_amount_bold": workbook.add_format({"bold": True}).set_num_format(
"#,##0." + "0" * currency_id.decimal_places
),
"format_percent_bold_italic": workbook.add_format(
{"bold": True, "italic": True}
).set_num_format("#,##0.00%"),
}
def _set_column_width(self, report_data):
"""Set width for all defined columns.
Columns are defined with `_get_report_columns` method.
"""
for position, column in report_data["columns"].items():
report_data["sheet"].set_column(position, position, column["width"])
def _write_report_title(self, title, report_data):
"""Write report title on current line using all defined columns width.
Columns are defined with `_get_report_columns` method.
"""
report_data["sheet"].merge_range(
report_data["row_pos"],
0,
report_data["row_pos"],
len(report_data["columns"]) - 1,
title,
report_data["formats"]["format_bold"],
)
report_data["row_pos"] += 3
def _write_report_footer(self, footer, report_data):
"""Write report footer .
Columns are defined with `_get_report_columns` method.
"""
if footer:
report_data["row_pos"] += 1
report_data["sheet"].merge_range(
report_data["row_pos"],
0,
report_data["row_pos"],
len(report_data["columns"]) - 1,
footer,
report_data["formats"]["format_left"],
)
report_data["row_pos"] += 1
def _write_filters(self, filters, report_data):
"""Write one line per filters on starting on current line.
Columns number for filter name is defined
with `_get_col_count_filter_name` method.
Columns number for filter value is define
with `_get_col_count_filter_value` method.
"""
col_name = 1
col_count_filter_name = self._get_col_count_filter_name()
col_count_filter_value = self._get_col_count_filter_value()
col_value = col_name + col_count_filter_name + 1
for title, value in filters:
report_data["sheet"].merge_range(
report_data["row_pos"],
col_name,
report_data["row_pos"],
col_name + col_count_filter_name - 1,
title,
report_data["formats"]["format_header_left"],
)
report_data["sheet"].merge_range(
report_data["row_pos"],
col_value,
report_data["row_pos"],
col_value + col_count_filter_value - 1,
value,
)
report_data["row_pos"] += 1
report_data["row_pos"] += 2
def write_array_title(self, title, report_data):
"""Write array title on current line using all defined columns width.
Columns are defined with `_get_report_columns` method.
"""
report_data["sheet"].merge_range(
report_data["row_pos"],
0,
report_data["row_pos"],
len(report_data["columns"]) - 1,
title,
report_data["formats"]["format_bold"],
)
report_data["row_pos"] += 1
def write_array_header(self, report_data):
"""Write array header on current line using all defined columns name.
Columns are defined with `_get_report_columns` method.
"""
for col_pos, column in report_data["columns"].items():
report_data["sheet"].write(
report_data["row_pos"],
col_pos,
column["header"],
report_data["formats"]["format_header_center"],
)
report_data["row_pos"] += 1
def write_line(self, line_object, report_data):
"""Write a line on current line using all defined columns field name.
Columns are defined with `_get_report_columns` method.
"""
for col_pos, column in report_data["columns"].items():
value = getattr(line_object, column["field"])
cell_type = column.get("type", "string")
if cell_type == "many2one":
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value.name or "",
report_data["formats"]["format_right"],
)
elif cell_type == "string":
if (
hasattr(line_object, "account_group_id")
and line_object.account_group_id
):
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_bold"],
)
else:
report_data["sheet"].write_string(
report_data["row_pos"], col_pos, value or ""
)
elif cell_type == "amount":
if (
hasattr(line_object, "account_group_id")
and line_object.account_group_id
):
cell_format = report_data["formats"]["format_amount_bold"]
else:
cell_format = report_data["formats"]["format_amount"]
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), cell_format
)
elif cell_type == "amount_currency":
if line_object.currency_id:
format_amt = self._get_currency_amt_format(line_object, report_data)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
report_data["row_pos"] += 1
def write_line_from_dict(self, line_dict, report_data):
"""Write a line on current line"""
for col_pos, column in report_data["columns"].items():
value = line_dict.get(column["field"], False)
cell_type = column.get("type", "string")
if cell_type == "string":
if (
line_dict.get("account_group_id", False)
and line_dict["account_group_id"]
):
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_bold"],
)
else:
if (
not isinstance(value, str)
and not isinstance(value, bool)
and not isinstance(value, int)
):
value = value and value.strftime("%d/%m/%Y")
report_data["sheet"].write_string(
report_data["row_pos"], col_pos, value or ""
)
elif cell_type == "amount":
if (
line_dict.get("account_group_id", False)
and line_dict["account_group_id"]
):
cell_format = report_data["formats"]["format_amount_bold"]
else:
cell_format = report_data["formats"]["format_amount"]
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), cell_format
)
elif cell_type == "amount_currency":
if line_dict.get("currency_name", False):
format_amt = self._get_currency_amt_format_dict(
line_dict, report_data
)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
elif cell_type == "currency_name":
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_right"],
)
report_data["row_pos"] += 1
def write_initial_balance(self, my_object, label, report_data):
"""Write a specific initial balance line on current line
using defined columns field_initial_balance name.
Columns are defined with `_get_report_columns` method.
"""
col_pos_label = self._get_col_pos_initial_balance_label()
report_data["sheet"].write(
report_data["row_pos"],
col_pos_label,
label,
report_data["formats"]["format_right"],
)
for col_pos, column in report_data["columns"].items():
if column.get("field_initial_balance"):
value = getattr(my_object, column["field_initial_balance"])
cell_type = column.get("type", "string")
if cell_type == "string":
report_data["sheet"].write_string(
report_data["row_pos"], col_pos, value or ""
)
elif cell_type == "amount":
report_data["sheet"].write_number(
report_data["row_pos"],
col_pos,
float(value),
report_data["formats"]["format_amount"],
)
elif cell_type == "amount_currency":
if my_object.currency_id:
format_amt = self._get_currency_amt_format(
my_object, report_data
)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
elif column.get("field_currency_balance"):
value = getattr(my_object, column["field_currency_balance"])
cell_type = column.get("type", "string")
if cell_type == "many2one":
if my_object.currency_id:
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value.name or "",
report_data["formats"]["format_right"],
)
report_data["row_pos"] += 1
def write_initial_balance_from_dict(self, my_object, label, report_data):
"""Write a specific initial balance line on current line
using defined columns field_initial_balance name.
Columns are defined with `_get_report_columns` method.
"""
col_pos_label = self._get_col_pos_initial_balance_label()
report_data["sheet"].write(
report_data["row_pos"],
col_pos_label,
label,
report_data["formats"]["format_right"],
)
for col_pos, column in report_data["columns"].items():
if column.get("field_initial_balance"):
value = my_object.get(column["field_initial_balance"], False)
cell_type = column.get("type", "string")
if cell_type == "string":
report_data["sheet"].write_string(
report_data["row_pos"], col_pos, value or ""
)
elif cell_type == "amount":
report_data["sheet"].write_number(
report_data["row_pos"],
col_pos,
float(value),
report_data["formats"]["format_amount"],
)
elif cell_type == "amount_currency":
if my_object["currency_id"]:
format_amt = self._get_currency_amt_format(
my_object, report_data
)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
elif column.get("field_currency_balance"):
value = my_object.get(column["field_currency_balance"], False)
cell_type = column.get("type", "string")
if cell_type == "many2one":
if my_object["currency_id"]:
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value.name or "",
report_data["formats"]["format_right"],
)
report_data["row_pos"] += 1
def write_ending_balance(self, my_object, name, label, report_data):
"""Write a specific ending balance line on current line
using defined columns field_final_balance name.
Columns are defined with `_get_report_columns` method.
"""
for i in range(0, len(report_data["columns"])):
report_data["sheet"].write(
report_data["row_pos"],
i,
"",
report_data["formats"]["format_header_right"],
)
row_count_name = self._get_col_count_final_balance_name()
col_pos_label = self._get_col_pos_final_balance_label()
report_data["sheet"].merge_range(
report_data["row_pos"],
0,
report_data["row_pos"],
row_count_name - 1,
name,
report_data["formats"]["format_header_left"],
)
report_data["sheet"].write(
report_data["row_pos"],
col_pos_label,
label,
report_data["formats"]["format_header_right"],
)
for col_pos, column in report_data["columns"].items():
if column.get("field_final_balance"):
value = getattr(my_object, column["field_final_balance"])
cell_type = column.get("type", "string")
if cell_type == "string":
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_header_right"],
)
elif cell_type == "amount":
report_data["sheet"].write_number(
report_data["row_pos"],
col_pos,
float(value),
report_data["formats"]["format_header_amount"],
)
elif cell_type == "amount_currency":
if my_object.currency_id:
format_amt = self._get_currency_amt_header_format(
my_object, report_data
)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
elif column.get("field_currency_balance"):
value = getattr(my_object, column["field_currency_balance"])
cell_type = column.get("type", "string")
if cell_type == "many2one":
if my_object.currency_id:
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value.name or "",
report_data["formats"]["format_header_right"],
)
report_data["row_pos"] += 1
def write_ending_balance_from_dict(self, my_object, name, label, report_data):
"""Write a specific ending balance line on current line
using defined columns field_final_balance name.
Columns are defined with `_get_report_columns` method.
"""
for i in range(0, len(report_data["columns"])):
report_data["sheet"].write(
report_data["row_pos"],
i,
"",
report_data["formats"]["format_header_right"],
)
row_count_name = self._get_col_count_final_balance_name()
col_pos_label = self._get_col_pos_final_balance_label()
report_data["sheet"].merge_range(
report_data["row_pos"],
0,
report_data["row_pos"],
row_count_name - 1,
name,
report_data["formats"]["format_header_left"],
)
report_data["sheet"].write(
report_data["row_pos"],
col_pos_label,
label,
report_data["formats"]["format_header_right"],
)
for col_pos, column in report_data["columns"].items():
if column.get("field_final_balance"):
value = my_object.get(column["field_final_balance"], False)
cell_type = column.get("type", "string")
if cell_type == "string":
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_header_right"],
)
elif cell_type == "amount":
report_data["sheet"].write_number(
report_data["row_pos"],
col_pos,
float(value),
report_data["formats"]["format_header_amount"],
)
elif cell_type == "amount_currency":
if my_object["currency_id"] and value:
format_amt = self._get_currency_amt_format_dict(
my_object, report_data
)
report_data["sheet"].write_number(
report_data["row_pos"], col_pos, float(value), format_amt
)
elif column.get("field_currency_balance"):
value = my_object.get(column["field_currency_balance"], False)
cell_type = column.get("type", "string")
if cell_type == "many2one":
if my_object["currency_id"]:
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_header_right"],
)
elif cell_type == "currency_name":
report_data["sheet"].write_string(
report_data["row_pos"],
col_pos,
value or "",
report_data["formats"]["format_header_right"],
)
report_data["row_pos"] += 1
def _get_currency_amt_format(self, line_object, report_data):
""" Return amount format specific for each currency. """
if "account_group_id" in line_object and line_object["account_group_id"]:
format_amt = report_data["formats"]["format_amount_bold"]
field_prefix = "format_amount_bold"
else:
format_amt = report_data["formats"]["format_amount"]
field_prefix = "format_amount"
if "currency_id" in line_object and line_object.get("currency_id", False):
field_name = "{}_{}".format(field_prefix, line_object["currency_id"].name)
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = report_data["workbook"].add_format()
report_data["field_name"] = format_amt
format_amount = "#,##0." + (
"0" * line_object["currency_id"].decimal_places
)
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_format_dict(self, line_dict, report_data):
""" Return amount format specific for each currency. """
if line_dict.get("account_group_id", False) and line_dict["account_group_id"]:
format_amt = report_data["formats"]["format_amount_bold"]
field_prefix = "format_amount_bold"
else:
format_amt = report_data["formats"]["format_amount"]
field_prefix = "format_amount"
if line_dict.get("currency_id", False) and line_dict["currency_id"]:
if isinstance(line_dict["currency_id"], int):
currency = self.env["res.currency"].browse(line_dict["currency_id"])
else:
currency = line_dict["currency_id"]
field_name = "{}_{}".format(field_prefix, currency.name)
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = report_data["workbook"].add_format()
report_data["field_name"] = format_amt
format_amount = "#,##0." + ("0" * currency.decimal_places)
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_header_format(self, line_object, report_data):
""" Return amount header format for each currency. """
format_amt = report_data["formats"]["format_header_amount"]
if line_object.currency_id:
field_name = "format_header_amount_%s" % line_object.currency_id.name
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = report_data["workbook"].add_format(
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
)
report_data["field_name"] = format_amt
format_amount = "#,##0." + (
"0" * line_object.currency_id.decimal_places
)
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_header_format_dict(self, line_object, report_data):
""" Return amount header format for each currency. """
format_amt = report_data["formats"]["format_header_amount"]
if line_object["currency_id"]:
field_name = "format_header_amount_%s" % line_object["currency_name"]
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = report_data["workbook"].add_format(
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
)
report_data["field_name"] = format_amt
format_amount = "#,##0." + (
"0" * line_object["currency_id"].decimal_places
)
format_amt.set_num_format(format_amount)
return format_amt
def _generate_report_content(self, workbook, report, data, report_data):
"""
Allow to fetch report content to be displayed.
"""
raise NotImplementedError()
def _get_report_complete_name(self, report, prefix, data=None):
if report.company_id:
suffix = " - {} - {}".format(
report.company_id.name, report.company_id.currency_id.name
)
return prefix + suffix
return prefix
def _get_report_name(self, report, data=False):
"""
Allow to define the report name.
Report name will be used as sheet name and as report title.
:return: the report name
"""
raise NotImplementedError()
def _get_report_footer(self):
"""
Allow to define the report footer.
:return: the report footer
"""
return False
def _get_report_columns(self, report):
"""
Allow to define the report columns
which will be used to generate report.
:return: the report columns as dict
:Example:
{
0: {'header': 'Simple column',
'field': 'field_name_on_my_object',
'width': 11},
1: {'header': 'Amount column',
'field': 'field_name_on_my_object',
'type': 'amount',
'width': 14},
}
"""
raise NotImplementedError()
def _get_report_filters(self, report):
"""
:return: the report filters as list
:Example:
[
['first_filter_name', 'first_filter_value'],
['second_filter_name', 'second_filter_value']
]
"""
raise NotImplementedError()
def _get_col_count_filter_name(self):
"""
:return: the columns number used for filter names.
"""
raise NotImplementedError()
def _get_col_count_filter_value(self):
"""
:return: the columns number used for filter values.
"""
raise NotImplementedError()
def _get_col_pos_initial_balance_label(self):
"""
:return: the columns position used for initial balance label.
"""
raise NotImplementedError()
def _get_col_count_final_balance_name(self):
"""
:return: the columns number used for final balance name.
"""
raise NotImplementedError()
def _get_col_pos_final_balance_label(self):
"""
:return: the columns position used for final balance label.
"""
raise NotImplementedError()

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="report_asset_barcode">
<div style="width: 32%; display: inline-table; height: 10rem;">
<table class="table table-bordered mb-0" style="border: 2px solid black;">
<tr>
<th class="table-active text-left" style="height: 4rem;">
<strong t-field="asset.display_name"/>
</th>
</tr>
<tr>
<td class="text-center align-middle" style="height: 6rem;">
<t t-if="asset.barcode">
<img alt="Barcode" t-if="len(asset.barcode) == 13" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN13', quote_plus(asset.barcode or ''), 600, 150)" style="width:100%;height:4rem;"/>
<img alt="Barcode" t-elif="len(asset.barcode) == 8" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN8', quote_plus(asset.barcode or ''), 600, 150)" style="width:100%;height:4rem;"/>
<img alt="Barcode" t-else="" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('Code128', quote_plus(asset.barcode or ''), 600, 150)" style="width:100%;height:4rem"/>
<span t-field="asset.barcode"/>
</t>
<t t-else=""><span class="text-muted">No barcode available</span></t>
</td>
</tr>
</table>
</div>
</template>
<template id="report_assetbarcode">
<t t-call="web.basic_layout">
<div class="page">
<t t-foreach="docs" t-as="asset">
<t t-call="exp_asset_base.report_asset_barcode">
<t t-set="asset" t-value="asset"/>
</t>
</t>
</div>
</t>
</template>
<record id="report_account_asset_barcode" model="ir.actions.report">
<field name="name">Asset Barcode (PDF)</field>
<field name="model">account.asset</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">exp_asset_base.report_assetbarcode</field>
<field name="report_file">exp_asset_base.report_assetbarcode</field>
<field name="print_report_name">'Assets barcode - %s' % (object.name)</field>
<field name="binding_model_id" ref="exp_asset_base.model_account_asset"/>
<field name="binding_type">report</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="label_barcode_account_asset_view">
<t t-foreach="docs" t-as="asset">
<t t-translation="off">
^XA
^FO100,50
^A0N,44,33^FD<t t-esc="asset.display_name"/>^FS
<t t-if="asset.barcode">
^FO100,100^BY3
^BCN,100,Y,N,N
^FD<t t-esc="asset.barcode"/>^FS
</t>
^XZ
</t>
</t>
</template>
<record id="label_barcode_account_asset" model="ir.actions.report">
<field name="name">Asset Barcode (ZPL)</field>
<field name="model">account.asset</field>
<field name="report_type">qweb-text</field>
<field name="report_name">exp_asset_base.label_barcode_account_asset_view</field>
<field name="report_file">exp_asset_base.label_barcode_account_asset_view</field>
<field name="binding_model_id" ref="exp_asset_base.model_account_asset"/>
<field name="binding_type">report</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,126 @@
# Copyright 2018 Forest and Biomass Romania
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, models
from dateutil.rrule import rrule, MONTHLY
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from datetime import datetime
class AssetDepreciationReportXslx(models.AbstractModel):
_name = 'report.asset_depreciation_report_xlsx'
_inherit = 'report.asset_abstract_report_xlsx'
_description = 'asset_depreciation_report_xlsx'
def _get_report_name(self, report):
return _('Fixed Asset Register')
def _get_report_columns(self, report):
return {
0: {'width': 5},
1: {'width': 12},
2: {'width': 20},
3: {'width': 12},
4: {'width': 12},
5: {'width': 12},
6: {'width': 12},
7: {'width': 12},
8: {'width': 12},
9: {'width': 12},
10: {'width': 12},
11: {'width': 12},
12: {'width': 12},
13: {'width': 12},
14: {'width': 12},
15: {'width': 12},
16: {'width': 12},
17: {'width': 12},
18: {'width': 12},
19: {'width': 12},
}
def _get_report_filters(self, report):
return [
[
_('Duration'), _('From: ') + report.start_date + ' ' + _('To: ') + report.end_date
],
[
_('Categories'), ', '.join([c.name for c in report.category_ids]),
],
]
def _get_col_count_filter_name(self):
return 1
def _get_col_count_filter_value(self):
return 3
def _generate_report_content(self, workbook, report):
# For each category
depreciation_line = self.env['account.asset.depreciation.line']
start_date = datetime.strptime(report.start_date, DF)
end_date = datetime.strptime(report.end_date, DF)
periods = [dt.strftime("%b-%y") for dt in rrule(MONTHLY, dtstart=start_date, until=end_date)]
seq = 1
depreciation_register = self.env['report_asset_register_depreciation']
for category in report.category_ids:
# Write category info
self.sheet.write(self.row_pos, 0, seq, self.format_header1)
self.sheet.merge_range(self.row_pos, 1, self.row_pos, 2, category.name, self.format_header1)
percentage = 100/(category.method_number*category.method_period/12)
self.sheet.write(self.row_pos, 3, str(round(percentage,2))+"%", self.format_header1)
self.sheet.write(self.row_pos, 4, "", self.format_header1)
self.sheet.merge_range(self.row_pos, 5, self.row_pos, 4+len(periods), "DEPRECIATION BY MONTH", self.format_header1)
self.sheet.write(self.row_pos, 5+len(periods), "Depr'n.", self.format_header1)
self.sheet.write(self.row_pos, 6+len(periods), "Accu Deprn.", self.format_header1)
self.sheet.write(self.row_pos, 7+len(periods), "NBV", self.format_header1)
self.row_pos += 1
#Write Header
self.sheet.write(self.row_pos, 0, "", self.format_header2)
self.sheet.write(self.row_pos, 1, "Date", self.format_header2)
self.sheet.write(self.row_pos, 2, "Description of Asset", self.format_header2)
self.sheet.write(self.row_pos, 3, "Ref. Doc.", self.format_header2)
self.sheet.write(self.row_pos, 4, "Amount", self.format_header2)
column_pos = 4
for p in periods:
column_pos += 1
self.sheet.write(self.row_pos, column_pos, p, self.format_header2)
self.sheet.write(self.row_pos, column_pos+1, report.start_date+'-'+report.end_date, self.format_header2)
self.sheet.write(self.row_pos, column_pos+2, report.end_date, self.format_header2)
self.sheet.write(self.row_pos, column_pos+3, 'After '+report.end_date, self.format_header2)
self.row_pos += 1
#Write Asset
asset_ids = self.env['account.asset'].search([('category_id', '=', category.id),
('date', '<=', report.end_date)])
for asset in asset_ids:
self.sheet.write(self.row_pos, 0, "", self.format_center)
self.sheet.write(self.row_pos, 1, asset.date, self.format_center)
self.sheet.write(self.row_pos, 2, asset.name, self.format_center)
self.sheet.write(self.row_pos, 3, asset.invoice_id.name, self.format_center)
self.sheet.write(self.row_pos, 4, asset.value, self.format_center)
column_pos = 4
fy_depreciation = 0
for p in periods:
column_pos += 1
depreciation = depreciation_register.search([('report_id', '=', report.id),
('asset_id', '=', asset.id),
('period', '=', p)])
amount = sum([d.amount for d in depreciation])
fy_depreciation += amount
self.sheet.write(self.row_pos, column_pos, amount, self.format_center)
self.sheet.write(self.row_pos, column_pos+1, fy_depreciation, self.format_center)
accu = depreciation_line.read_group([('depreciation_date', '<=', report.end_date),
('asset_id','=', asset.id)],
['asset_id', 'amount'], ['asset_id'])
accu_depreciation = accu and accu[0].get('amount') or 0
self.sheet.write(self.row_pos, column_pos+2, accu_depreciation, self.format_center)
self.sheet.write(self.row_pos, column_pos+3, asset.value - accu_depreciation, self.format_center)
self.row_pos += 1
seq += 1
self.row_pos += 1

View File

@ -0,0 +1,74 @@
# © 2016 Julien Coux (Camptocamp)
# © 2018 Forest and Biomass Romania SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from dateutil.rrule import rrule, MONTHLY
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
from datetime import datetime, timedelta
class AssetRegisterReport(models.TransientModel):
""" Here, we just define class fields.
For methods, go more bottom at this file.
The class hierarchy is :
* AssetRegisterReport
** Asset Category
*** Asset
**** AssetRegisterReportDepreciation
"""
_name = 'report_asset_register'
# Filters fields, used for data computation
category_ids = fields.Many2many('account.asset.category')
start_date = fields.Date()
end_date = fields.Date()
depreciation_ids = fields.One2many('report_asset_register_depreciation', 'report_id')
@api.one
def compute_data_for_report(self):
self.depreciation_ids.unlink()
depreciation = self.env['account.asset.depreciation.line']
depreciation_register = self.env['report_asset_register_depreciation']
asset = self.env['account.asset'].search([('category_id', 'in', self.category_ids.ids),
('date', '<=', self.end_date)])
start_date = datetime.strptime(self.start_date, DF).replace(day=1)
end_date = datetime.strptime(self.end_date, DF) + timedelta(days=1)
dates = [dt for dt in rrule(MONTHLY, dtstart=start_date, until=end_date)]
dates[0] = datetime.strptime(self.start_date, DF)
for p in range(0, len(dates)):
start = dates[p]
end = p != len(dates)-1 and dates[p+1] or end_date
line = depreciation.search([('depreciation_date', '>=', start.strftime(DF)),
('depreciation_date', '<', end.strftime(DF)),
('asset_id', 'in', asset.ids),
('move_id', '!=', False)])
for l in line:
val = {
'report_id': self.id,
'asset_id': l.asset_id.id,
'period': start.strftime("%b-%y"),
'amount': l.amount,
'date': l.depreciation_date,
}
depreciation_register.create(val)
@api.multi
def print_report(self):
self.ensure_one()
return self.env['ir.actions.report'].search(
[('report_name', '=', 'asset_depreciation_report_xlsx'),
('report_type', '=', 'xlsx')], limit=1).report_action(self)
class AssetRegisterReportDepreciation(models.TransientModel):
_name = 'report_asset_register_depreciation'
report_id = fields.Many2one('report_asset_register', ondelete='cascade', index=True)
asset_id = fields.Many2one('account.asset')
period = fields.Char()
amount = fields.Float()
date = fields.Date()

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_report_asset_register_tree" model="ir.ui.view">
<field name="name">report_asset_register.tree</field>
<field name="model">report_asset_register</field>
<field name="arch" type="xml">
<tree>
<field name="start_date"/>
<field name="end_date"/>
<field name="category_ids" widget="many2many_tags"/>
</tree>
</field>
</record>
<record id="view_report_asset_register_form" model="ir.ui.view">
<field name="name">report_asset_register.form</field>
<field name="model">report_asset_register</field>
<field name="arch" type="xml">
<form>
<header>
<button name="compute_data_for_report" string="Compute" type="object"/>
</header>
<sheet>
<group>
<group>
<field name="start_date" required="1"/>
<field name="end_date" required="1"/>
</group>
<group>
<field name="category_ids" widget="many2many_tags" required="1"/>
</group>
</group>
<notebook>
<page string="Depreciations">
<field name="depreciation_ids" readonly="1">
<tree>
<field name="asset_id"/>
<field name="date"/>
<field name="amount"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record id="act_report_asset_register" model="ir.actions.act_window">
<field name="name">Asset Register</field>
<field name="res_model">report_asset_register</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_report_asset_register_tree"/>
</record>
</odoo>

View File

@ -0,0 +1,126 @@
# Copyright 2018 Forest and Biomass Romania
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, _
from datetime import datetime
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class AssetRegisterReportXslx(models.AbstractModel):
_name = 'report.report_asset_register_xlsx'
_inherit = 'report.asset_abstract_report_xlsx'
_description = 'report_asset_register_xlsx'
def _get_report_name(self, report, data=False):
return _('Asset Register')
def _get_report_columns(self, report):
return {
0: {'header': 'RN', 'width': 5},
1: {'header': 'Serial Number', 'width': 20},
2: {'header': 'Asset Name', 'width': 20},
3: {'header': 'Model Number', 'width': 14},
4: {'header': 'Asset Location', 'width': 14},
5: {'header': 'User', 'width': 14},
6: {'header': 'Supplier', 'width': 14},
7: {'header': 'Invoice Number', 'width': 20},
8: {'header': 'Invoice Date', 'width': 12},
9: {'header': 'Value', 'type': 'amount', 'width': 14},
10: {'header': 'Received Date', 'width': 16},
11: {'header': 'Warranty', 'width': 20},
12: {'header': 'Registration Number', 'width': 20},
13: {'header': 'Registration Date', 'width': 20},
14: {'header': '# Existing Depreciation', 'width': 20},
15: {'header': 'Existing Depreciation', 'width': 20},
16: {'header': 'First Depreciation', 'width': 20},
17: {'header': 'Depreciation %', 'width': 16},
18: {'header': 'Up to Date', 'width': 12},
19: {'header': 'Expired Days', 'width': 14},
20: {'header': 'Depreciation', 'width': 14},
21: {'header': 'Accumulated Depreciation', 'width': 20},
22: {'header': 'Net Value', 'width': 14},
}
def _get_report_filters(self, report):
return []
def _get_col_count_filter_name(self):
return 0
def _get_col_count_filter_value(self):
return 0
def _generate_report_content(self, workbook, report, data, report_data):
# For each asset
seq = 1
# Header
report_data["sheet"].write(report_data["row_pos"], 0, "رقم", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 1, "رقم الأصل", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 2, "الاسم العلمي", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 3, "رقم التصنيع/الهيكل", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 4, "موقع الأصل", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 5, "المستخدم", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 6, "المورد", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 7, "رقم الفاتورة", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 8, "تاريخ الفاتورة", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 9, "القيمة", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 10, "تاريخ الإستلام", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 11, "تفاصيل الضمان", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 12, "رقم القيد", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 13, "تاريخ القيد", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 14, "عدد الاستهلاكات السابقة", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 15, "قيمة الاستهلاك السابق", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 16, "تاريخ اول اسستهلاك", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 17, "نسبة الاستهلاك", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 18, "تاريخ الاحتساب", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 19, "ايام الاستهلاك", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 20, "استهلاك السنة", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 21, "الاستهلاك التراكمي", report_data["formats"]["format_header_center"])
report_data["sheet"].write(report_data["row_pos"], 22, "صافي القيمة الدفترية", report_data["formats"]["format_header_center"])
report_data["row_pos"] += 1
self.write_array_header(report_data)
for asset in report:
# Write asset line
report_data["sheet"].write_number(report_data["row_pos"], 0, seq, report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 1, asset.serial_no or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 2, asset.name or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 3, asset.model or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 4, asset.location_id.name or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 5, asset.responsible_user_id.name or '', report_data["formats"]["format_center"])
partner = []
invoice = []
for orginal_move in asset.original_move_line_ids:
partner.append(orginal_move.partner_id.name)
invoice.append(orginal_move.move_id.name)
report_data["sheet"].write_string(report_data["row_pos"], 6, partner or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 7, invoice or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 8, asset.acquisition_date and asset.acquisition_date.strftime("%d/%m/%Y") or '', report_data["formats"]["format_center"])
report_data["sheet"].write_number(report_data["row_pos"], 9, float(asset.original_value), report_data["formats"]["format_amount"])
report_data["sheet"].write_string(report_data["row_pos"], 10, asset.receive_date and asset.receive_date.strftime("%d/%m/%Y") or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 11, asset.warranty_contract or '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 12, '', report_data["formats"]["format_center"])
report_data["sheet"].write_string(report_data["row_pos"], 13, '', report_data["formats"]["format_center"])
report_data["sheet"].write_number(report_data["row_pos"], 14, asset.depreciation_number_import, report_data["formats"]["format_amount"])
report_data["sheet"].write_number(report_data["row_pos"], 15, asset.already_depreciated_amount_import, report_data["formats"]["format_amount"])
report_data["sheet"].write_string(report_data["row_pos"], 16, asset.first_depreciation_date_import and asset.first_depreciation_date_import.strftime("%d/%m/%Y") or '', report_data["formats"]["format_center"])
percentage = 100/(asset.method_number*int(asset.method_period)/12)
report_data["sheet"].write_number(report_data["row_pos"], 17, float(percentage), report_data["formats"]["format_amount"])
posted_depreciation_move_ids = asset.depreciation_move_ids.filtered(
lambda x: x.state == 'posted' and not x.asset_value_change and not x.reversal_move_id).sorted(
key=lambda l: l.date)
calc_date = posted_depreciation_move_ids[-1].date
report_data["sheet"].write_string(report_data["row_pos"], 18, calc_date and calc_date.strftime("%d/%m/%Y") or '', report_data["formats"]["format_center"])
first_dept = asset.first_depreciation_date_import or asset.receive_date or asset.date
delta = calc_date and first_dept and calc_date-first_dept
days = delta and delta.days or 0
report_data["sheet"].write_number(report_data["row_pos"], 19, float(days), report_data["formats"]["format_amount"])
report_data["sheet"].write_number(report_data["row_pos"], 20, float((asset.original_value-asset.already_depreciated_amount_import)*percentage/100), report_data["formats"]["format_amount"])
report_data["sheet"].write_number(report_data["row_pos"], 21, float(asset.original_value-asset.value_residual), report_data["formats"]["format_amount"])
report_data["sheet"].write_number(report_data["row_pos"], 22, float(asset.book_value), report_data["formats"]["format_amount"])
seq += 1
report_data["row_pos"] += 1

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<report id="action_report_asset_register_xlsx"
model="account.asset"
name="report_asset_register_xlsx"
file="report_asset_register_xlsx"
string="Asset register XLSX"
report_type="xlsx"
menu="True"/>
<!--report id="action_report_asset_depr_register_xlsx"
model="report_asset_register"
name="asset_depreciation_report_xlsx"
file="asset depreciation report"
string="Asset Depreciation register XLSX"
report_type="xlsx"
menu="True"/-->
</odoo>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="group_asset_assessment" model="res.groups">
<field name="name">Asset Assessment</field>
<field name="category_id" ref="base.module_category_accounting_accounting"/>
</record>
<record model="ir.module.category" id="asset_category">
<field name="name">Assets Managment</field>
</record>
<record id="group_assets_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="exp_asset_base.asset_category"/>
</record>
<record id="group_assets_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="exp_asset_base.asset_category"/>
<field name="implied_ids" eval="[(4, ref('exp_asset_base.group_assets_user'))]"/>
</record>
<!-- end -->
</odoo>

View File

@ -0,0 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_asset_manufacturer,account.asset.manufacturer,model_account_asset_manufacturer,account.group_account_readonly,1,0,0,0
access_asset_manufacturer_manager,account.asset.manufacturer,model_account_asset_manufacturer,account.group_account_manager,1,1,1,1
access_asset_location,account.asset.location,model_account_asset_location,account.group_account_readonly,1,0,0,0
access_asset_location_manager,account.asset.location,model_account_asset_location,account.group_account_manager,1,1,1,1
access_asset_adjustment,account.asset.adjustment,model_account_asset_adjustment,account.group_account_readonly,1,0,0,0
access_asset_adjustment_manager,account.asset.adjustment,model_account_asset_adjustment,account.group_account_manager,1,1,1,1
access_asset_adjustment_line,account.asset.adjustment.line,model_account_asset_adjustment_line,account.group_account_readonly,1,0,0,0
access_asset_adjustment_line_manager,account.asset.adjustment.line,model_account_asset_adjustment_line,account.group_account_manager,1,1,1,1
access_account_asset_modify,access.account.asset.modify,model_account_asset_modify,account.group_account_user,1,1,1,1
access_asset_pause,access.asset.pause,model_asset_pause,account.group_account_user,1,1,1,1
access_asset_sell,access.asset.sell,model_asset_sell,account.group_account_user,1,1,1,1
access_asset_state_operation5_manager,account.state.4multi.operation,model_asset_state2,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_asset_manufacturer account.asset.manufacturer model_account_asset_manufacturer account.group_account_readonly 1 0 0 0
3 access_asset_manufacturer_manager account.asset.manufacturer model_account_asset_manufacturer account.group_account_manager 1 1 1 1
4 access_asset_location account.asset.location model_account_asset_location account.group_account_readonly 1 0 0 0
5 access_asset_location_manager account.asset.location model_account_asset_location account.group_account_manager 1 1 1 1
6 access_asset_adjustment account.asset.adjustment model_account_asset_adjustment account.group_account_readonly 1 0 0 0
7 access_asset_adjustment_manager account.asset.adjustment model_account_asset_adjustment account.group_account_manager 1 1 1 1
8 access_asset_adjustment_line account.asset.adjustment.line model_account_asset_adjustment_line account.group_account_readonly 1 0 0 0
9 access_asset_adjustment_line_manager account.asset.adjustment.line model_account_asset_adjustment_line account.group_account_manager 1 1 1 1
10 access_account_asset_modify access.account.asset.modify model_account_asset_modify account.group_account_user 1 1 1 1
11 access_asset_pause access.asset.pause model_asset_pause account.group_account_user 1 1 1 1
12 access_asset_sell access.asset.sell model_asset_sell account.group_account_user 1 1 1 1
13 access_asset_state_operation5_manager account.state.4multi.operation model_asset_state2 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="asset_adjustment_line_tree">
<field name="name">account.asset.adjustment.line.tree</field>
<field name="model">account.asset.adjustment.line</field>
<field name="arch" type="xml">
<list string="Asset Adjustment">
<field name="asset_id"/>
<field name="serial_no"/>
<field name="barcode"/>
<field name="adjustment_id"/>
<field name="asset_status"/>
<field name="exist"/>
</list>
</field>
</record>
<record model="ir.ui.view" id="asset_adjustment_tree">
<field name="name">account.asset.adjustment.tree</field>
<field name="model">account.asset.adjustment</field>
<field name="arch" type="xml">
<list string="Asset Adjustment">
<field name="name"/>
<field name="date"/>
<field name="type"/>
<field name="state"/>
</list>
</field>
</record>
<record model="ir.ui.view" id="asset_adjustment_form">
<field name="name">account.asset.adjustment.form</field>
<field name="model">account.asset.adjustment</field>
<field name="arch" type="xml">
<form string="Asset Adjustment">
<header>
<button name="act_progress" invisible="state != 'draft'" string="Start" type="object" class="oe_highlight"/>
<button name="act_done" invisible="state != 'in_progress'" groups='exp_asset_base.group_assets_manager' string="Confirm" type="object" class="oe_highlight"/>
<button name="act_cancel" invisible="state != 'in_progress'" groups="exp_asset_base.group_assets_manager" string="Reject" type="object"/>
<button name="act_draft" invisible="state != 'cancel'" groups='exp_asset_base.group_assets_manager' string="Set to Draft" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,done"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="barcode" nolabel="1" placeholder="Barcode..."/>
</h1>
</div>
<group>
<group>
<field name="name"/>
<field name="type"/>
</group>
<group>
<field name="date"/>
<field name="product_id"
invisible="type != 'product'"
required="type == 'product'"
/>
<field name="model_id"
invisible="type != 'model'"
required="type == 'model'"/>
</group>
</group>
<notebook>
<page string="Details">
<field name="adjustment_line_ids" nolabel="1">
<list editable="top"
decoration-success="exist==True" create="0" delete="0">
<field name="asset_id" readonly="1"/>
<field name="serial_no"/>
<field name="barcode"/>
<field name="asset_status2"
readonly="exist == False"
required="exist == True"/>
<field name="exist"/>
</list>
</field>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="action_asset_adjustment" model="ir.actions.act_window">
<field name="name">Asset Adjustment</field>
<field name="res_model">account.asset.adjustment</field>
<field name="view_mode">list,form</field>
</record>
</odoo>

View File

@ -0,0 +1,343 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Asset Manufacturer -->
<record id="action_account_asset_manufacturer" model="ir.actions.act_window">
<field name="name">Assets Manufacturer</field>
<field name="res_model">account.asset.manufacturer</field>
<field name="view_mode">list,form</field>
</record>
<record model="ir.ui.view" id="asset_manufacturer_form">
<field name="name">account.asset.manufacturer.form</field>
<field name="model">account.asset.manufacturer</field>
<field name="arch" type="xml">
<form string="Asset Location">
<sheet>
<group>
<field name="name"/>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<!-- Asset Location -->
<record id="action_account_asset_location" model="ir.actions.act_window">
<field name="name">Assets Locations</field>
<field name="res_model">account.asset.location</field>
<field name="view_mode">list,form</field>
</record>
<record model="ir.ui.view" id="asset_location_form">
<field name="name">account.asset.location.form</field>
<field name="model">account.asset.location</field>
<field name="arch" type="xml">
<form string="Asset Location">
<sheet>
<div class="oe_title">
<h1>
<field name="name" nolabel="1" placeholder="Location Name..."/>
</h1>
</div>
<group>
<group>
<field name="code"/>
<field name="parent_id"/>
</group>
<group>
<field name="type"/>
</group>
</group>
<notebook invisible="type != 'view'" >
<page string="Child Locations">
<field name="child_id" nolabel="1">
<list editable="top">
<field name="name"/>
<field name="code"/>
<field name="type"/>
</list>
</field>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<!-- Asset Register -->
<record id="view_account_asset_search" model="ir.ui.view">
<field name="name">account.asset.search</field>
<field name="model">account.asset</field>
<field name="inherit_id" ref="odex30_account_asset.view_account_asset_search"/>
<field name="arch" type="xml">
<field name="name" position="attributes">
<attribute name="filter_domain">['|', ('name','ilike',self), ('barcode','ilike',self)]</attribute>
</field>
<field name="model_id" position="after">
<field name="responsible_dept_id"/>
<field name="model"/>
<field name="serial_no"/>
<field name="analytic_distribution"/>
</field>
<filter name="model" position="after">
<filter string="Responsible Department" name="responsible_department" domain="[]"
context="{'group_by':'responsible_dept_id'}"/>
<filter string="Cost Center" name="cost_center" domain="[]"
context="{'group_by':'analytic_distribution'}"/>
</filter>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_form">
<field name="name">account.asset.form</field>
<field name="model">account.asset</field>
<field name="inherit_id" ref="odex30_account_asset.view_account_asset_form"/>
<field name="arch" type="xml">
<header position="inside">
<button type="object" name="act_unlock" groups='exp_asset_base.group_assets_manager' string="Unlock" invisible="state != 'open'" />
<button type="object" name="act_lock" groups='exp_asset_base.group_assets_manager' string="Lock" invisible="state != 'unlock'" />
</header>
<div name="button_box" position="inside">
<button class="oe_stat_button" name="open_asset_adjustment" type="object" icon="fa-pencil"
invisible="asset_type != 'purchase'">
<field string="Adjustments" name="asset_adjustment_count" widget="statinfo"/>
</button>
</div>
<div class="oe_title" position="before">
<field name="asset_picture" widget="image" class="oe_avatar"
invisible="state == 'model' or asset_type != 'purchase'"
/>
</div>
<field name="name" position="after">
<span invisible="state == 'model' or asset_type != 'purchase'">-</span>
<field name="barcode" placeholder="Barcode"
invisible="state == 'model' or asset_type != 'purchase'"/>
</field>
<div class="oe_title" position="after">
<group string="Basic Info" invisible="asset_type == 'purchase'">
<group>
<field name="responsible_user_id"
invisible="asset_type == 'purchase'"/>
<field name="limit"
invisible="state != 'model' or asset_type != 'purchase'"/>
<field name="manufacturer_id"
invisible="state == 'model' or asset_type != 'purchase'"/>
<field name="serial_no" readonly="1"
invisible="state == 'model' or asset_type != 'purchase'"/>
<field name="product_id"
invisible="state == 'model' or asset_type != 'purchase'"/>
</group>
<group>
<field name="responsible_dept_id" invisible="asset_type == 'purchase'"/>
<field name="company_id" invisible="1"/>
<field name="model" invisible="state == 'model' or asset_type != 'purchase'"/>
<field name="receive_date" invisible="state == 'model' or asset_type != 'purchase'"/>
<field name="note" invisible="state == 'model' or asset_type != 'purchase'"/>
<field name="status" invisible="1"/>
</group>
</group>
</div>
<xpath expr="//button[@name='validate']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='set_to_draft']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='set_to_running']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='resume_after_pause']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<notebook position="before">
<group string="Warranty"
invisible="state == 'model' or asset_type != 'purchase'">
<group>
<field name="service_provider_id"/>
<field name="next_maintenance_date"/>
<field name="warranty_contract"/>
</group>
<group>
<field name="warranty_period"/>
<field name="warranty_end_date"/>
</group>
</group>
</notebook>
<sheet position="after">
</sheet>
</field>
</record>
<record id="view_account_asset_asset_kanban" model="ir.ui.view">
<field name="name">account.asset.asset.inherit.kanban</field>
<field name="model">account.asset</field>
<field name="priority">1</field>
<field name="inherit_id" ref="odex30_account_asset.view_account_asset_kanban"/>
<field name="arch" type="xml">
<xpath expr='//kanban' position="inside">
<field name="id"/>
<field name="serial_no"/>
<field name="barcode"/>
<field name="status"/>
<field name="asset_picture"/>
<field name="activity_ids"/>
<field name="asset_type" invisible="1"/>
</xpath>
<xpath expr='//kanban/templates/t/div/div[1]' position="before">
<div class="row mb4"
invisible="state == 'model' or asset_type != 'purchase'">
<div class="col-6">
<div class="o_kanban_image">
<img t-att-src="record.asset_picture.raw_value
? 'data:image/png;base64,' + record.asset_picture.raw_value
: '/web/static/img/placeholder.png'"
class="o_image_64_cover"
alt="Asset"/>
</div>
</div>
<div class="col-6 text-right">
<strong>
<span>
<field name="status"/>
</span>
</strong>
</div>
</div>
</xpath>
<xpath expr='//kanban/templates/t/div/div[1]' position="after">
<div class="row mb4"
invisible="state == 'model' or asset_type != 'purchase'">
<div class="col-6">
<strong>
<span>
<field name="serial_no"/>
</span>
</strong>
</div>
<div class="col-6 text-right">
<strong>
<field name="barcode"/>
</strong>
</div>
</div>
</xpath>
<xpath expr='//kanban/templates/t/div' position="inside">
<div class="oe_kanban_content">
<div class="o_kanban_record_bottom">
<div class="oe_kanban_bottom_left">
<field name="activity_ids" widget="kanban_activity"/>
</div>
<div class="oe_kanban_bottom_right">
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="view_account_asset_asset_purchase_tree" model="ir.ui.view">
<field name="name">account.asset.inherit.tree</field>
<field name="model">account.asset</field>
<field name="priority">1</field>
<field name="inherit_id" ref="odex30_account_asset.view_account_asset_tree"/>
<field name="arch" type="xml">
<field name="name" position="after">
<field name="barcode"/>
<field name="serial_no"/>
</field>
<field name="state" position="before">
<field name="status" string="Custody Status"/>
</field>
</field>
</record>
<record model="ir.actions.act_window" id="odex30_account_asset.action_account_asset_form">
<field name="name">Assets</field>
<field name="res_model">account.asset</field>
<field name="domain">[('asset_type', '=', 'purchase'), ('state', '!=', 'model'), ('parent_id', '=', False)]
</field>
<field name="context">{'asset_type': 'purchase', 'default_asset_type': 'purchase'}</field>
<field name="view_ids"
eval="[(5, 0, 0),
(0, 0, {'view_mode': 'kanban', 'view_id': ref('view_account_asset_asset_kanban')}),
(0, 0, {'view_mode': 'list', 'view_id': ref('view_account_asset_asset_purchase_tree')}),
(0, 0, {'view_mode': 'form', 'view_id': ref('odex30_account_asset.view_account_asset_form')})]"/>
</record>
<!-- Asset Analysis -->
<record id="view_account_asset_pivot" model="ir.ui.view">
<field name="name">account.asset.pivot</field>
<field name="model">account.asset</field>
<field name="arch" type="xml">
<pivot string="Assets Analysis">
<!-- -->
<field name="name" type="row"/>
<field name="original_value" type="measure"/>
<field name="book_value" type="measure"/>
<field name="value_residual"/>
</pivot>
</field>
</record>
<record id="view_account_asset_graph" model="ir.ui.view">
<field name="name">account.asset.graph</field>
<field name="model">account.asset</field>
<field name="arch" type="xml">
<graph string="Assets Analysis" type="bar">
<field name="name" type="row"/>
<!-- -->
<field name="original_value" type="measure"/>
<field name="book_value" type="measure"/>
<field name="value_residual" type="measure"/>
</graph>
</field>
</record>
<record id="action_account_asset_graph" model="ir.actions.act_window">
<field name="name">Assets Analysis</field>
<field name="view_mode">graph,pivot</field>
<field name="view_id" ref="view_account_asset_graph"/>
<field name="res_model">account.asset</field>
</record>
<!-- Depreciation Analysis -->
<record id="view_account_asset_depreciation_pivot" model="ir.ui.view">
<field name="name">account.asset.depreciation.pivot</field>
<field name="model">account.move</field>
<field name="arch" type="xml">
<pivot string="Depreciation Analysis">
<field name="date" string="Depreciation Date" interval="year" type="row"/>
<field name="amount_total" string="Depreciation" type="measure"/>
<field name="asset_depreciated_value" type="measure"/>
<field name="asset_remaining_value" type="measure"/>
</pivot>
</field>
</record>
<record id="view_account_asset_depreciation_graph" model="ir.ui.view">
<field name="name">account.asset.graph</field>
<field name="model">account.move</field>
<field name="arch" type="xml">
<graph string="Depreciation Analysis" type="bar">
<field name="date" string="Depreciation Date" interval="year" type="row"/>
<field name="amount_total" string="Depreciation" type="measure"/>
<field name="asset_depreciated_value" type="measure"/>
<field name="asset_remaining_value" type="measure"/>
</graph>
</field>
</record>
<record id="action_account_asset_depreciation_analysis" model="ir.actions.act_window">
<field name="name">Depreciation Analysis</field>
<field name="view_mode">graph,pivot</field>
<field name="view_id" ref="view_account_asset_depreciation_graph"/>
<field name="res_model">account.move</field>
<field name="domain">[('asset_id', '!=', False)]</field>
</record>
</odoo>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="asset_modify_tree">
<field name="name">account.asset.modify.tree</field>
<field name="model">account.asset.modify</field>
<field name="arch" type="xml">
<tree string="Modify Asset">
<field name="asset_id"/>
<field name="name"/>
<field name="date"/>
<field name="state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="asset_modify_form">
<field name="name">account.asset.modify.form</field>
<field name="model">account.asset.modify</field>
<field name="arch" type="xml">
<form string="Modify Asset">
<header>
<button name="act_confirm" groups='exp_asset_base.group_assets_manager' invisible="state != 'draft'" string="Confirm" type="object" class="oe_highlight"/>
<button name="act_approve" groups="exp_asset_base.group_assets_manager" invisible="state != 'confirm'" string="Approve" type="object" class="oe_highlight"/>
<button name="modify" groups="exp_asset_base.group_assets_manager" invisible="state != 'approve'" string="Done" type="object" class="oe_highlight"/>
<button name="act_draft" groups="exp_asset_base.group_assets_manager" invisible="state not in ['approve','confirm']" string="Set to Draft" type="object"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,approve,done"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="name" nolabel="1" placeholder="Modification..." readonly="state != 'draft'"/>
</h1>
</div>
<group>
<group string="Modification">
<field name="asset_id" readonly="state != 'draft'" context="{'form_view_ref': 'odex30_account_asset.view_account_asset_form'}"/>
<field name="need_date" invisible="1"/>
<field name="gain_value" invisible="1"/>
<field name="name" placeholder="Modification reason" required="1" readonly="state != 'draft'"/>
<field name="date" invisible="need_date = False" readonly="required = True"/>
</group>
<group string="New Values">
<label for="method_number"/>
<div class="o_row">
<field name="method_number" required="1" readonly="state != 'draft'"/>
<field name="method_period" required="1" nolabel="1" readonly="state != 'draft'"/>
</div>
<field name="value_residual" readonly="state != 'draft'"/>
<field name="salvage_value" readonly="state != 'draft'"/>
</group>
<group string="Increase Accounts" invisible="gain_value = False" readonly="state != 'draft'" >
<field name="account_asset_id" required="gain_value != False" readonly="state != 'draft'"/>
<field name="account_asset_counterpart_id" required="gain_value != False" readonly="state != 'draft'"/>
<field name="account_depreciation_id" required="gain_value != False" readonly="state != 'draft'"/>
<field name="account_depreciation_expense_id" required="gain_value != False" readonly="state != 'draft'"/>
</group>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="action_asset_modify" model="ir.actions.act_window">
<field name="name">Asset Modification</field>
<field name="res_model">account.asset.modify</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="asset_modify_menu"
parent="menu_account_asset_operation"
action="action_asset_modify"
name="Assets Modification" sequence="1"/>
</odoo>

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="asset_pause_tree">
<field name="name">asset.pause.tree</field>
<field name="model">asset.pause</field>
<field name="arch" type="xml">
<tree string="Modify Asset">
<field name="asset_id"/>
<field name="date"/>
<field name="state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="asset_pause_form">
<field name="name">asset.pause.form</field>
<field name="model">asset.pause</field>
<field name="arch" type="xml">
<form string="Pause Asset">
<header>
<button groups='exp_asset_base.group_assets_manager' name="act_confirm" invisible="state != 'draft'" string="Confirm" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_approve" invisible="state != 'confirm'" string="Approve" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="do_action" invisible="state != 'approve'" string="Done" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_draft" invisible="state not in ['confirm','approve']" string="Set to Draft" type="object"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,approve,done"/>
</header>
<sheet>
<group>
<group>
<field name="asset_id" required="1" readonly="state != 'draft'" context="{'form_view_ref': 'odex30_account_asset.view_account_asset_form'}"/>
<field name="date" required="1" readonly="state != 'draft'"/>
</group>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="action_asset_pause" model="ir.actions.act_window">
<field name="name">Asset Pause</field>
<field name="res_model">asset.pause</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="asset_pause_menu"
parent="menu_account_asset_operation"
action="action_asset_pause"
name="Assets Pause" sequence="2"/>
</odoo>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="asset_sell_tree">
<field name="name">asset.sell.tree</field>
<field name="model">asset.sell</field>
<field name="arch" type="xml">
<tree string="Sell Asset">
<field name="asset_id"/>
<field name="action"/>
<field name="state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="asset_sell_form">
<field name="name">asset.sell.form</field>
<field name="model">asset.sell</field>
<field name="arch" type="xml">
<form string="Sell Asset">
<header>
<button groups='exp_asset_base.group_assets_manager' name="act_confirm" invisible="state != 'draft'" string="Confirm" type="object" class="oe_highlight"/>
<button groups='exp_asset_base.group_assets_manager' name="act_approve" invisible="state != 'confirm'" string="Approve" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="do_action" invisible="state != 'approve'" string="Done" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_draft" invisible="state not in ['approve','confirm']" string="Set to Draft" type="object"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,approve,done"/>
</header>
<sheet>
<field name="select_invoice_line_id" invisible="1"/>
<field name="gain_or_loss" invisible="1"/>
<field name="company_id" invisible="1"/>
<group>
<group>
<field name="asset_id" readonly="state != 'draft'" context="{'form_view_ref': 'odex30_account_asset.view_account_asset_form'}"/>
<field name="action" readonly="state != 'draft'"/>
<field name="invoice_id" options="{'no_create': True}" readonly="state != 'draft'" invisible="action != 'sell'" required="action = 'sell'" />
<field name="invoice_line_id" options="{'no_create': True}" readonly="state != 'draft'" invisible="select_invoice_line_id = False" required="select_invoice_line_id = True"/>
</group>
<group>
<field name="gain_account_id" invisible="gain_or_loss != 'gain'" readonly="state != 'draft'" required="gain_or_loss = 'gain'" />
<field name="loss_account_id" invisible="gain_or_loss != 'loss'" readonly="state != 'draft'" required="gain_or_loss = 'loss'"/>
</group>
</group>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="action_asset_sell" model="ir.actions.act_window">
<field name="name">Asset Sell</field>
<field name="res_model">asset.sell</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="asset_sell_menu"
parent="menu_account_asset_operation"
action="action_asset_sell"
name="Assets Sell" sequence="4"/>
</odoo>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<menuitem id="menu_account_asset_management_main"
name="Assets Management" groups="exp_asset_base.group_assets_manager,exp_asset_base.group_assets_user"
sequence="11" web_icon="exp_asset_base,static/description/assets.png"/>
<!-- Asset Register -->
<menuitem id="odex30_account_asset.menu_action_account_asset_form"
parent="menu_account_asset_management_main"
action="odex30_account_asset.action_account_asset_form"
name="Assets Register" sequence="1"
groups="account.group_account_readonly"/>
<!-- Asset Adjustment -->
<menuitem id="menu_account_asset_adjustment"
parent="menu_account_asset_management_main"
action="action_asset_adjustment"
name="Assets Adjustment"
sequence="4"/>
<!-- Asset Operation -->
<menuitem id="menu_account_asset_operation_main"
name="Assets Operations"
parent="menu_account_asset_management_main"
sequence="3"/>
<menuitem id="menu_account_asset_operation"
name="Assets Operations"
parent="menu_account_asset_operation_main"
sequence="4"/>
<!-- Asset Reporting -->
<menuitem id="menu_account_asset_reporting_main"
parent="menu_account_asset_management_main"
name="Reporting"
sequence="5"/>
<menuitem id="menu_account_asset_graph"
parent="menu_account_asset_reporting_main"
action="action_account_asset_graph"
name="Assets Analysis"
sequence="1"/>
<menuitem id="menu_account_Depreciation_graph"
parent="menu_account_asset_reporting_main"
action="action_account_asset_depreciation_analysis"
name="Depreciation Analysis"
sequence="2"/>
<menuitem id="odex30_account_asset.menu_action_account_report_assets" name="Depreciation Schedule"
action="odex30_account_asset.action_account_report_assets"
parent="menu_account_asset_reporting_main"
sequence="3"/>
<!--
<menuitem id="menu_report_asset_register"
parent="menu_account_asset_reporting_main"
action="act_report_asset_register"
sequence="4"/-->
<!-- Asset Configurations -->
<menuitem id="menu_account_asset_configuration_main"
parent="menu_account_asset_management_main"
name="Configurations"
sequence="7"/>
<menuitem id="odex30_account_asset.menu_action_account_asset_model_form"
parent="menu_account_asset_configuration_main"
action="odex30_account_asset.action_account_asset_model_form"
groups="account.group_account_manager"
sequence="1" />
<menuitem id="menu_account_asset_location"
parent="menu_account_asset_configuration_main"
action="action_account_asset_location"
name="Assets Locations"
sequence="2"/>
<menuitem id="menu_account_manufacturer"
parent="menu_account_asset_configuration_main"
action="action_account_asset_manufacturer"
name="Manufacturer"
sequence="3"/>
<menuitem id="menu_account_asset_vendors"
parent="menu_account_asset_configuration_main"
action="base.action_partner_supplier_form"
name="Vendors"
sequence="4"/>
<menuitem id="menu_account_asset_products"
parent="menu_account_asset_configuration_main"
action="product.product_normal_action"
name="Products"
sequence="5"/>
</data>
</odoo>

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from . import models

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# © 2016 ACSONE SA/NV (<http://acsone.eu>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Asset Custody Management',
'summary': 'Custody Operations for Asset',
'description': '''
Manage Assets transfer between locations, departments and employees
''',
'version': '1.0.0',
'category': 'Odex30-Accounting/Odex30-Accounting',
'author': 'Expert Co. Ltd.',
'website': 'http://www.exp-sa.com',
'license': 'AGPL-3',
'application': False,
'installable': True,
'depends': [
'exp_asset_base'
],
'data': [
'data/asset_data.xml',
'security/ir.model.access.csv',
'views/account_asset_view.xml',
'views/account_asset_adjustment_view.xml',
'views/account_asset_custody_multi_operation.xml',
'views/account_asset_custody_operation_view.xml',
'reports/asset_adjustment_report.xml',
'views/menus.xml'
],
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<record id="asset_operation_sequence" model="ir.sequence">
<field name="name">Asset Operation Sequence</field>
<field name="code">asset.operation.seq</field>
<field name="prefix">ASS OP/%(range_year)s/</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="True" name="use_date_range"/>
<field eval="False" name="company_id"/>
<field name="padding">6</field>
</record>
<record id="asset_multi_operation_sequence" model="ir.sequence">
<field name="name">Asset Multi Operation Sequence</field>
<field name="code">asset.multi.operation.seq</field>
<field name="prefix">ASS MOP/%(range_year)s/</field>
<field eval="1" name="number_next"/>
<field eval="1" name="number_increment"/>
<field eval="True" name="use_date_range"/>
<field eval="False" name="company_id"/>
<field name="padding">6</field>
</record>
<record id="asset_state" model="asset.states">
<field name="name">good</field>
</record>
<record id="asset_state2" model="asset.states">
<field name="name">scarp</field>
</record>
<record id="asset_state33" model="asset.states">
<field name="name">available</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,883 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * exp_asset_custody
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0+e-20210105\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-05-19 04:38+0000\n"
"PO-Revision-Date: 2021-05-19 04:38+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__asset_operation_count
msgid "# Done Operations"
msgstr "العمليات المعتمدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction
msgid "Action Needed"
msgstr "إجراء مطلوب"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_ids
msgid "Activities"
msgstr "الأنشطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_decoration
msgid "Activity Exception Decoration"
msgstr "زخرفة استثناء النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_state
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_state
msgid "Activity State"
msgstr "حالة النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_icon
msgid "Activity Type Icon"
msgstr "أيقونة نوع النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__amount
msgid "Amount"
msgstr "المبلغ"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset"
msgstr "الأصل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset Account"
msgstr "حساب الأصل"
#. module: exp_asset_custody
#: model:ir.actions.report,name:exp_asset_custody.action_asset_adjustment_report
#: model:ir.model,name:exp_asset_custody.model_account_asset_adjustment
msgid "Asset Adjustment"
msgstr "جرد الأصول"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset_multi_operation
msgid "Asset Multi Operation"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset.py:0
#, python-format
msgid "Asset Operations"
msgstr "عمليات الأصول"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Asset Operations in done state"
msgstr "العمليات المعتمدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__asset_status
msgid "Asset Status"
msgstr "حالة العهد"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset
msgid "Asset/Revenue Recognition"
msgstr "أصل/ إيرادات مقدمة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Assets Adjustment Report"
msgstr "تقرير جرد الأصول"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_assignment
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
msgid "Assets Assignment"
msgstr "إسناد عهدة"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_operation_main
msgid "Assets Operations"
msgstr "عمليات الأصول"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_release
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
msgid "Assets Release"
msgstr "إرجاع عهدة"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_transfer
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Assets Transfer"
msgstr "نقل العهدة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__assigned
msgid "Assigned"
msgstr "مسند"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__reserved
msgid "Reserved"
msgstr "محجوز"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__assignment
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__assignment
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_assignment
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_assignment
msgid "Assignment"
msgstr "أسناد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Assignment Info"
msgstr "معلومات الإسناد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_attachment_count
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_attachment_count
msgid "Attachment Count"
msgstr "عدد المرفقات"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__barcode
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__barcode
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Barcode"
msgstr "باركود"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned
msgid "Barcode Scanned"
msgstr "باركود"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Barcode..."
msgstr "الباركود..."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__department
msgid "By Department"
msgstr "الإدارة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__employee
msgid "By Employee"
msgstr "الموظف"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_adjustment__type__location
msgid "By Location"
msgstr "الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__cancel
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__cancel
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "Cancel"
msgstr "إلغاء"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "Confirm"
msgstr "تأكيد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_uid
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_uid
msgid "Created by"
msgstr "أنشئ بواسطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__create_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__create_date
msgid "Created on"
msgstr "أنشئ في"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Current"
msgstr "الحالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__department_id
msgid "Current Department"
msgstr "الإدارة الحالية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__employee_id
msgid "Current Employee"
msgstr "الموظف الحالي"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Current Info"
msgstr "المعلومات الحالية"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form
msgid "Custody Info"
msgstr "معلومات العهدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_period
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_period
msgid "Custody Period"
msgstr "فترة العهدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__custody_type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__custody_type
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Custody Type"
msgstr "نوع العهدة"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_custody_operation
msgid "Custody operations"
msgstr "عمليات العهد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__date
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Date"
msgstr "التاريخ"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Date:"
msgstr "التاريخ:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_department_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Department"
msgstr "الإدارة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Description:"
msgstr "الوصف:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__display_name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__display_name
msgid "Display Name"
msgstr "الاسم المعروض"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__done
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__done
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Done"
msgstr "المنتهية"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__draft
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__draft
msgid "Draft"
msgstr "مسودة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_employee_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_employee_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Employee"
msgstr "الموظف"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_follower_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_follower_ids
msgid "Followers"
msgstr "المتابعون"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_channel_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_channel_ids
msgid "Followers (Channels)"
msgstr "المتابعون (القنوات)"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_partner_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_partner_ids
msgid "Followers (Partners)"
msgstr "المتابعون (الشركاء)"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_type_icon
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_type_icon
msgid "Font awesome icon e.g. fa-tasks"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__general
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__general
msgid "General"
msgstr "عام"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__good
msgid "Good"
msgstr "جيد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Group By..."
msgstr "تجميع بـ..."
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__id
msgid "ID"
msgstr "المُعرف"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_exception_icon
msgid "Icon"
msgstr "الأيقونة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_icon
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_icon
msgid "Icon to indicate an exception activity."
msgstr "الأيقونة للإشارة إلى استثناء النشاط"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread
msgid "If checked, new messages require your attention."
msgstr "إذا كان محددًا، فهناك رسائل جديدة تحتاج لرؤيتها."
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr "إذا كان محددًا، فقد حدث خطأ في تسليم بعض الرسائل."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__state__in_progress
msgid "In Progress"
msgstr "جاري"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_is_follower
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_is_follower
msgid "Is Follower"
msgstr "متابع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation____last_update
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation____last_update
msgid "Last Modified on"
msgstr "آخر تعديل في"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_uid
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_uid
msgid "Last Updated by"
msgstr "آخر تحديث بواسطة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__write_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__write_date
msgid "Last Updated on"
msgstr "آخر تحديث في"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__new_location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__current_location_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__new_location_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_search
msgid "Location"
msgstr "الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_main_attachment_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_main_attachment_id
msgid "Main Attachment"
msgstr "المرفقات"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose an asset in all operation line."
msgstr ""
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose custody period for all operation lines."
msgstr "الرجاء التاكد من إدخال فترة العهدة في جميع العمليات."
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you choose custody type for all operation lines."
msgstr "الرجاء التاكد من إدخال نوع العهدة في جميع العمليات."
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "Make sure you enter the return date for all temporary custodies."
msgstr "الرجاء التاكد من إدخال تاريخ الإرجاع للعهد المؤقتة."
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__manual
msgid "Manual"
msgstr "يدوي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error
msgid "Message Delivery error"
msgstr "خطأ في تسليم الرسائل"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_ids
msgid "Messages"
msgstr "الرسائل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Missing Assets:"
msgstr "الأصول المفقودة:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__model_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Model"
msgstr "النموذج"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__multi_operation_id
msgid "Multi Operation"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_assignment
msgid "Multiple Assignment"
msgstr "إسناد العهد"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_release
msgid "Multiple Release"
msgstr "إرجاع العهد"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_multi_asset_transfer
msgid "Multiple Transfer"
msgstr "نقل العهد"
#. module: exp_asset_custody
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_multi_operation
msgid "Multiple operations"
msgstr "العمليات المتعددة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__name
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__name
msgid "Name"
msgstr "الإسم"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "New"
msgstr "جديد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Department"
msgstr "الإدارة الجديدة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Employee"
msgstr "الموظف الجديد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "New Location"
msgstr "الموقع الجديد"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_date_deadline
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_date_deadline
msgid "Next Activity Deadline"
msgstr "الموعد النهائي للنشاط التالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_summary
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_summary
msgid "Next Activity Summary"
msgstr "ملخص النشاط التالي"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_type_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_type_id
msgid "Next Activity Type"
msgstr "نوع النشاط التالي"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "No asset found with the selected barcode"
msgstr "لم يتم العثور على أصل لهذا الباركود"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__note
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__note
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Note"
msgstr "ملاحظة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_needaction_counter
msgid "Number of Actions"
msgstr "عدد الإجراءات"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset__asset_operation_count
msgid "Number of done asset operations"
msgstr ""
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_error_counter
msgid "Number of errors"
msgstr "عدد الاخطاء"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_needaction_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_needaction_counter
msgid "Number of messages which requires an action"
msgstr "عدد الرسائل التي تتطلب إجراء"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_has_error_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_has_error_counter
msgid "Number of messages with delivery error"
msgstr "عدد الرسائل الحادث بها خطأ في التسليم"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__message_unread_counter
msgid "Number of unread messages"
msgstr "عدد الرسائل الجديدة"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_operation.py:0
#, python-format
msgid "Only draft operations can be deleted."
msgstr "لا يمكن حذف العملية الا في الحالة مبدئية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__operation_ids
msgid "Operation"
msgstr "عملية"
#. module: exp_asset_custody
#: model:ir.actions.act_window,name:exp_asset_custody.action_account_asset_operation_analysis
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_operation_graph
msgid "Operation Analysis"
msgstr "تحليل العمليات"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_form
msgid "Operations"
msgstr "العمليات"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__pending
msgid "Pending"
msgstr "معلق"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__permanent
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__permanent
msgid "Permanent"
msgstr "دائمة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_type__personal
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_type__personal
msgid "Personal"
msgstr "شخصية"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__product_id
msgid "Product"
msgstr "المنتج"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__purpose
msgid "Purpose"
msgstr "الغرض"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Reject"
msgstr "رفض"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__release
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__release
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_release
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_release
msgid "Release"
msgstr "إرجاع"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Release Info"
msgstr "معلومات الإرجاع"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
msgid "Release Location"
msgstr "موقع الإرجاع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__user_id
msgid "Responsible"
msgstr "المسئول"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_department_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__department_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Responsible Department"
msgstr "الإدارة المسئولة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__activity_user_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__responsible_user_id
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__activity_user_id
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Responsible User"
msgstr "الموظف المسئول"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__return_date
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__return_date
msgid "Return Date"
msgstr "تاريخ الإرجاع"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_has_sms_error
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_has_sms_error
msgid "SMS Delivery error"
msgstr "خطأ في تسليم الرسائل القصيرة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__status__scrap
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__asset_status__scrap
msgid "Scrap"
msgstr "تالف"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Serial No"
msgstr "المتسلسل"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "Set to Draft"
msgstr "تعيين كمسودة"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_release_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_transfer_tree
msgid "Setup"
msgstr "الإعداد"
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Signatures:"
msgstr ""
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_assignment_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_release_form
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_multi_transfer_form
msgid "Start"
msgstr "بدأ"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__state
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__state
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "State"
msgstr "الحالة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset__status
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Status"
msgstr "الحالة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_state
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_state
msgid ""
"Status based on activities\n"
"Overdue: Due date is already passed\n"
"Today: Activity date is today\n"
"Planned: Future activities."
msgstr "الأنشطة المستقبيلة"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__state__submit
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_assignment_tree
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_form
msgid "Submit"
msgstr "إرسال"
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset__custody_period__temporary
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__custody_period__temporary
msgid "Temporary"
msgstr "مؤقتة"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset.py:0
#, python-format
msgid "The period of %s is finished %s."
msgstr "فترة %s قد إنتهت %s."
#. module: exp_asset_custody
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_multi_operation__type__transfer
#: model:ir.model.fields.selection,name:exp_asset_custody.selection__account_asset_operation__type__transfer
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_asset_transfer
#: model:ir.ui.menu,name:exp_asset_custody.menu_account_multi_asset_transfer
msgid "Transfer"
msgstr "نقل"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_adjustment__type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__type
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__type
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.view_account_asset_operation_search
msgid "Type"
msgstr "النوع"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__activity_exception_decoration
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__activity_exception_decoration
msgid "Type of the exception activity on record."
msgstr "نوع النشاط الاستثنائي المسجل."
#. module: exp_asset_custody
#: model_terms:ir.ui.view,arch_db:exp_asset_custody.asset_adjustment_report
msgid "Type:"
msgstr "النوع:"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread
msgid "Unread Messages"
msgstr "الرسائل الجديدة"
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__message_unread_counter
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__message_unread_counter
msgid "Unread Messages Counter"
msgstr "عدد الرسائل الجديدة"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation___barcode_scanned
msgid "Value of the last barcode scanned."
msgstr "قيمة آخر باركود ممسوح ضوئيًا."
#. module: exp_asset_custody
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_multi_operation__website_message_ids
#: model:ir.model.fields,field_description:exp_asset_custody.field_account_asset_operation__website_message_ids
msgid "Website Messages"
msgstr "رسائل الموقع"
#. module: exp_asset_custody
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_multi_operation__website_message_ids
#: model:ir.model.fields,help:exp_asset_custody.field_account_asset_operation__website_message_ids
msgid "Website communication history"
msgstr "سجل تواصل الموقع"
#. module: exp_asset_custody
#: code:addons/exp_asset_custody/models/account_asset_multi_operation.py:0
#, python-format
msgid "You can not confirm operation without lines."
msgstr "لا يمكن تأكيد العملية دون إدخال التفاصيل"
#. module: exp_asset_custody
#: model:ir.model,name:exp_asset_custody.model_account_asset_operation
msgid "account.asset.operation"
msgstr ""

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from . import account_asset
from . import account_asset_operation
from . import account_asset_adjustment
from . import account_asset_multi_operation

View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import models, fields, api, _
class AccountAssetAsset(models.Model):
_inherit = 'account.asset'
custody_type = fields.Selection(
selection=[('personal', 'Personal'), ('general', 'General')],
)
custody_period = fields.Selection(
selection=[('temporary', 'Temporary'), ('permanent', 'Permanent')],
)
purpose = fields.Html()
return_date = fields.Date()
department_id = fields.Many2one(
comodel_name='hr.department',
string='Current Department'
)
employee_id = fields.Many2one(
comodel_name='hr.employee',
string='Current Employee'
)
status = fields.Selection(
selection_add=[('reserved', 'Reserved'), ('assigned', 'Assigned'), ('scrap', 'Scrap')]
)
asset_operation_count = fields.Integer(
compute='_asset_operation_count',
string='# Done Operations',
help="Number of done asset operations"
)
def _asset_operation_count(self):
for asset in self:
asset.asset_operation_count = len(
self.env['account.asset.operation'].search([('asset_id', '=', asset.id), ('state', '=', 'done')]))
def open_asset_operation(self):
return {
'name': _('Asset Operations'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.asset.operation',
'type': 'ir.actions.act_window',
'domain': [('asset_id', '=', self.id)],
'view_id': self.env.ref('exp_asset_custody.view_account_asset_operation_tree').id,
'views': [(self.env.ref('exp_asset_custody.view_account_asset_operation_tree').id, 'tree'),
(self.env.ref('exp_asset_custody.view_account_asset_operation_form').id, 'form')],
'context': {'active_model': False, 'search_default_done': True},
'flags': {'search_view': True, 'action_buttons': False},
}
@api.model
def _asset_cron(self):
super(AccountAssetAsset, self)._asset_cron()
today = fields.Date.today()
for asset in self.search([('return_date', '=', today)]):
self.env['mail.activity'].sudo().create({
'res_model_id': self.env.ref('account_asset.model_account_asset_asset').id,
'res_id': asset.id,
'user_id': asset.responsible_user_id.id,
'activity_type_id': self.env.ref('mail.mail_activity_data_todo').id,
'summary': _('The period of %s is finished %s.') % (asset.name, asset.return_date),
'date_deadline': asset.return_date,
})

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import api, fields, models, exceptions, _
class AccountAssetAdjustment(models.Model):
_inherit = 'account.asset.adjustment'
type = fields.Selection(
selection_add=[('department', 'By Department'),
('employee', 'By Employee'),
('location', 'By Location')],
states={'draft': [('readonly', False)]},
readonly=True,
)
department_id = fields.Many2one(
comodel_name='hr.department',
states={'draft': [('readonly', False)]},
readonly=True,
)
employee_id = fields.Many2one(
comodel_name='hr.employee',
states={'draft': [('readonly', False)]},
readonly=True,
)
location_id = fields.Many2one(
comodel_name='account.asset.location',
states={'draft': [('readonly', False)]},
readonly=True,
)
def build_domain(self):
return self.type == 'employee' and [('employee_id', '=', self.employee_id.id)] or \
(self.type == 'department' and [('department_id', '=', self.department_id.id)]) or \
(self.type == 'location' and [('location_id', '=', self.location_id.id)]) or \
super(AccountAssetAdjustment, self).build_domain()
@api.onchange('type')
def onchange_type(self):
self.employee_id = False
self.department_id = False
self.location_id = False
super(AccountAssetAdjustment, self).onchange_type()

View File

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import models, fields, api, exceptions, _
class AccountAssetMultiOperation(models.Model):
_name = 'account.asset.multi.operation'
_description = 'Asset Multi Operation'
_inherit = ['mail.thread', 'mail.activity.mixin', 'barcodes.barcode_events_mixin']
name = fields.Char(
states={'draft': [('readonly', False)]},
default='/', readonly=True
)
date = fields.Date(
default=fields.Date.context_today,
index=True, copy=False, readonly=True, required=True,
states={'draft': [('readonly', False)]}
)
type = fields.Selection(
selection=[('assignment', 'Assignment'),
('release', 'Release'),
('transfer', 'Transfer')],
states={'draft': [('readonly', False)]},
readonly=True, required=True
)
barcode = fields.Char(
states={'in_progress': [('readonly', False)]},
readonly=True,
)
responsible_user_id = fields.Many2one(
comodel_name='res.users',
default=lambda self: self.env.user,
states={'draft': [('readonly', False)]},
readonly=True, required=True
)
responsible_department_id = fields.Many2one(
comodel_name='hr.department',
)
new_employee_id = fields.Many2one(
comodel_name='hr.employee',
states={'draft': [('readonly', False)]},
readonly=True, string='Employee',
)
new_department_id = fields.Many2one(
comodel_name='hr.department',
states={'draft': [('readonly', False)]},
readonly=True, string='Department',
)
new_location_id = fields.Many2one(
comodel_name='account.asset.location',
states={'draft': [('readonly', False)]},
readonly=True, string='Location',
)
manual = fields.Boolean()
note = fields.Text(
states={'draft': [('readonly', False)]},
readonly=True, required=True
)
state = fields.Selection(
selection=[('draft', 'Draft'),
('in_progress', 'In Progress'),
('done', 'Done'),
('cancel', 'Cancel')],
required=True, default='draft'
)
operation_ids = fields.One2many(
'account.asset.operation', 'multi_operation_id',
states={'in_progress': [('readonly', False)]},
readonly=False,
)
@api.model
def create(self, values):
values['name'] = self.env['ir.sequence'].with_context(
ir_sequence_date=values['date']).next_by_code('asset.multi.operation.seq')
return super(AccountAssetMultiOperation, self).create(values)
def act_progress(self):
self.state = 'in_progress'
def act_confirm(self):
if not self.operation_ids:
raise exceptions.Warning(_('You can not confirm operation without lines.'))
for opt in self.operation_ids:
self.check_required_fields(opt)
opt.act_confirm()
self.state = 'done'
def act_reject(self):
self.state = 'cancel'
def act_draft(self):
self.state = 'draft'
def get_asset_domain(self):
if self.type == 'assignment':
return [('status', 'in', ['new','available'])]
elif self.type in ['transfer', 'release']:
return [('status', 'in', ['assigned'])]
return [('status', 'in', ['new', 'available', 'assigned', 'scrap'])]
@api.onchange('new_employee_id')
def onchange_new_employee(self):
self.new_department_id = self.new_employee_id.department_id.id
@api.onchange('barcode')
def onchange_barcode(self):
self.on_barcode_scanned(self.barcode)
def on_barcode_scanned(self, barcode):
if barcode:
operation_vals = self.get_operation_vals()
domain = self.get_asset_domain()
assets = self.barcode and self.env['account.asset'].search(domain + [('barcode', '=', barcode)])
self.barcode = False
if not assets:
raise exceptions.Warning(_('No asset found with the selected barcode'))
for s in assets:
operation_vals.update({
'asset_id': s.id,
'current_employee_id': s.employee_id.id,
'current_department_id': s.department_id.id,
'current_location_id': s.location_id.id,
#'state': 'submit',
})
self.operation_ids = [(0, 0, operation_vals)]
def get_operation_vals(self):
return {
'state': 'draft',
'type': self.type,
'date': self.date,
'note': self.note,
'multi_operation_id': self.id,
'user_id': self.responsible_user_id.id,
'new_employee_id': self.new_employee_id.id,
'new_department_id': self.new_department_id.id,
'new_location_id': self.new_location_id.id,
}
def check_required_fields(self, operation):
if not operation.asset_id:
raise exceptions.Warning(_('Make sure you choose an asset in all operation line.'))
elif not operation.return_date and operation.custody_period == 'temporary':
raise exceptions.Warning(_('Make sure you enter the return date for all temporary custodies.'))
elif not operation.custody_type and operation.type in ['assignment', 'transfer']:
raise exceptions.Warning(_('Make sure you choose custody type for all operation lines.'))
elif not operation.custody_period and operation.type in ['assignment', 'transfer']:
raise exceptions.Warning(_('Make sure you choose custody period for all operation lines.'))

View File

@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
# © Copyright (C) 2021 Expert Co. Ltd(<http:/www.exp-sa.com>)
from odoo import models, fields, api, exceptions, _
class AccountAssetOperation(models.Model):
_name = 'account.asset.operation'
_description = 'Asset Operation'
_inherit = ['mail.thread', 'mail.activity.mixin']
multi_operation_id = fields.Many2one(comodel_name='account.asset.multi.operation')
name = fields.Char(required=True, default='/')
type = fields.Selection(selection=[('assignment', 'Assignment'), ('release', 'Release'),
('transfer', 'Transfer')], required=True)
date = fields.Date(default=fields.Date.context_today, index=True, copy=False, readonly=True, required=True,
states={'draft': [('readonly', False)]})
user_id = fields.Many2one(comodel_name='res.users',default=lambda self: self.env.user,
states={'draft': [('readonly', False)]},string='Responsible',readonly=True)
asset_id = fields.Many2one(comodel_name='account.asset')
statea = fields.Selection(related='asset_id.status')
barcode = fields.Char(compute="_compute_related_fields", store=True)
department_id = fields.Many2one(comodel_name='hr.department',string='Responsible Department',
compute="_compute_related_fields", store=True)
model_id = fields.Many2one(comodel_name='account.asset',compute="_compute_related_fields",store=True)
state = fields.Selection(selection=[('draft', 'Draft'),('submit', 'Submit'),('done', 'Done'),('pending', 'Pending')
,('cancel', 'Cancel')],required=True, default='draft')
note = fields.Text(states={'draft': [('readonly', False)]},readonly=True,)
# Asset Custody Operation
custody_type = fields.Selection(selection=[('personal', 'Personal'), ('general', 'General')],
states={'draft': [('readonly', False)]},readonly=True,)
custody_period = fields.Selection(selection=[('temporary', 'Temporary'), ('permanent', 'Permanent')],
states={'draft': [('readonly', False)]},readonly=True)
return_date = fields.Date(states={'draft': [('readonly', False)]},readonly=True)
current_employee_id = fields.Many2one(comodel_name='hr.employee',
states={'draft': [('readonly', False)]},readonly=True, string='Employee')
current_department_id = fields.Many2one(comodel_name='hr.department',states={'draft': [('readonly', False)]},
readonly=True, string='Department', )
current_location_id = fields.Many2one(comodel_name='account.asset.location',states={'draft': [('readonly', False)]},
readonly=True, string='Location')
new_employee_id = fields.Many2one(comodel_name='hr.employee', string='Employee')
new_department_id = fields.Many2one(comodel_name='hr.department', string='Department', )
new_location_id = fields.Many2one(comodel_name='account.asset.location', string='Location')
amount = fields.Float(states={'draft': [('readonly', False)]}, readonly=True, )
asset_status = fields.Selection(selection=[('good', 'Good'), ('scrap', 'Scrap')],
states={'draft': [('readonly', False)]}, readonly=True, )
asset_statuso = fields.Selection(related='asset_id.status')
asset_status2 = fields.Many2one(
comodel_name='asset.states',
string='Asset Status',states={'draft': [('readonly', False)]})
product_id = fields.Many2one(comodel_name='product.product',
domain=[('property_account_expense_id.can_create_asset', '=', True),
('property_account_expense_id.user_type_id.internal_group', '=', 'asset')],
states={'draft': [('readonly', False)]}, readonly=True)
def action_read_operation(self):
self.ensure_one()
return {
'name': self.display_name,
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'account.asset.operation',
'res_id': self.id,
}
@api.depends('asset_id', 'asset_id.model_id', 'asset_id.responsible_dept_id', 'asset_id.barcode')
def _compute_related_fields(self):
for operation in self:
operation.barcode = operation.asset_id.barcode
operation.model_id = operation.asset_id.model_id.id
operation.department_id = operation.asset_id.responsible_dept_id.id
@api.model
def create(self, values):
values['name'] = self.env['ir.sequence'].with_context(
ir_sequence_date=values['date']).next_by_code('asset.operation.seq')
return super(AccountAssetOperation, self).create(values)
def unlink(self):
if self.search([('state', '!=', 'draft'), ('id', 'in', self.ids)]):
raise exceptions.Warning(_('Only draft operations can be deleted.'))
return super(AccountAssetOperation, self).unlink()
@api.model
def _get_tracked_fields(self):
fields = self.fields_get()
dels = [f for f in fields if f in models.LOG_ACCESS_COLUMNS or f.startswith('_') or f == 'id']
for x in dels:
del fields[x]
return set(fields)
@api.onchange('new_employee_id')
def onchange_new_employee(self):
self.new_department_id = self.new_employee_id.department_id.id
@api.onchange('asset_id')
def onchange_asset(self):
self.current_employee_id = self.asset_id.employee_id.id
self.current_department_id = self.asset_id.department_id.id
self.current_location_id = self.asset_id.location_id.id
def act_submit(self):
self.state = 'submit'
def act_confirm(self):
if not self.asset_id:
raise exceptions.Warning(_('Asset is required to confirm this operation.'))
if self.type in ('assignment', 'release', 'transfer'):
self.custody_confirm()
self.state = 'done'
def act_reject(self):
self.state = 'pending'
def act_cancel(self):
self.state = 'cancel'
def act_draft(self):
self.state = 'draft'
def custody_confirm(self):
self.asset_id.employee_id = self.new_employee_id.id
self.asset_id.department_id = self.new_department_id.id
self.asset_id.location_id = self.new_location_id.id
self.asset_id.custody_type = self.custody_type
self.asset_id.custody_period = self.custody_period
self.asset_id.return_date = self.return_date
self.asset_id.purpose = self.note
if self.type == 'assignment':
self.asset_id.status = 'assigned'
elif self.type == 'release':
self.asset_id.status = 'available'
"""
def sell_dispose_confirm(self):
super(AccountAssetOperation, self).sell_dispose_confirm()
self.asset_id.custody_type = False
self.asset_id.custody_period = False
self.asset_id.purpose = False
self.asset_id.return_date = False
self.asset_id.department_id = False
self.asset_id.employee_id = False
self.asset_id.location_id = False
self.asset_id.status = False
"""
class AccountAssestatus(models.Model):
_name = 'asset.states'
name = fields.Char(string='Name')

View File

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="asset_adjustment_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="web.html_container">
<t t-call="web.external_layout">
<t t-set="total_debit" t-value="0"/>
<t t-set="total_credit" t-value="0"/>
<t t-set="o" t-value="doc"/>
<div class="page" style="font-size: 12pt !important;">
<center>
<h3>
Assets Adjustment Report
</h3>
</center>
<br/>
<br/>
<br/>
<table class="borderless" style="width: 100%;">
<tr>
<td style="width:15%;">
<p style="font-weight: bold !important;">Description:</p>
</td>
<td>
<span t-field="o.name"/>
</td>
<td style="width:15%;">
<p style="font-weight: bold !important;">Date:</p></td>
<td>
<span t-field="o.date"/>
</td>
</tr>
<tr>
<td style="width:15%;">
<p style="font-weight: bold !important;">Type:</p></td>
<td>
<span t-field="o.type"/>
</td>
</tr>
</table>
<br/>
<br/>
<table style="width:100%;">
<thead>
<tr>
<th>Asset</th>
<th>Barcode</th>
<th>Serial No</th>
<th>Location</th>
<th>Department</th>
<th>Employee</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr t-foreach="o.adjustment_line_ids.filtered(lambda r: r.exist == True)" t-as="l">
<td>
<span t-field="l.asset_id.name"/>
</td>
<td>
<span t-field="l.barcode"/>
</td>
<td>
<span t-field="l.serial_no"/>
</td>
<td>
<span t-field="l.asset_id.location_id.name"/>
</td>
<td>
<span t-field="l.asset_id.department_id.name"/>
</td>
<td>
<span t-field="l.asset_id.employee_id.name"/>
</td>
<td>
<span t-field="l.asset_status"/>
</td>
</tr>
</tbody>
</table>
<br/>
<p>
<h4>Missing Assets:</h4>
</p>
<table style="width:100%;">
<thead>
<tr>
<th>Asset</th>
<th>Barcode</th>
<th>Serial No</th>
<th>Location</th>
<th>Department</th>
<th>Employee</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr t-foreach="o.adjustment_line_ids.filtered(lambda r: r.exist == False)" t-as="l">
<td>
<span t-field="l.asset_id.name"/>
</td>
<td>
<span t-field="l.barcode"/>
</td>
<td>
<span t-field="l.serial_no"/>
</td>
<td>
<span t-field="l.asset_id.location_id.name"/>
</td>
<td>
<span t-field="l.asset_id.department_id.name"/>
</td>
<td>
<span t-field="l.asset_id.employee_id.name"/>
</td>
<td>
<span t-field="l.asset_status"/>
</td>
</tr>
</tbody>
</table>
<br/>
<p>
<h4>Signatures:</h4>
</p>
<table style="width:100%;height:200px;">
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
<tr>
<td>
<span/>
</td>
<td>
<span/>
</td>
</tr>
</table>
<style>
@font-face {
font-family: 'ae_AlMohanad';
src: local('ae_AlMohanad'), local('ae_AlMohanad'),
url('/account_gl_custom/static/fonts/ae_AlMohanad.ttf') format('truetype');
}
*{
font-family: ae_AlMohanad;
}
table {
border-collapse: collapse;
}
table{
border: 1px solid black;
}
td{
border: 1px solid grey;
padding: 5px 5px 5px 5px;
}
th{
border: 1px solid grey;
padding: 5px 5px 5px 5px;
font-weight: bold;
text-align:center;
background-color: #f5f5f5;
}
table.borderless,table.borderless td,table.borderless tr{
border: none !important;
}
</style>
</div>
</t>
</t>
</t>
</t>
</template>
<report id="action_asset_adjustment_report"
model="account.asset.adjustment"
string="Asset Adjustment"
report_type="qweb-pdf"
name="exp_asset_custody.asset_adjustment_report"
file="exp_asset_custody.asset_adjustment_report"
paperformat="base.paperformat_euro"
attachment_use="False"
/>
</odoo>

View File

@ -0,0 +1,6 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_asset_operation,account.asset.operation,model_account_asset_operation,account.group_account_readonly,1,0,0,0
access_asset_operation_manager,account.asset.operation,model_account_asset_operation,account.group_account_manager,1,1,1,1
access_asset_multi_operation,account.asset.multi.operation,model_account_asset_multi_operation,account.group_account_readonly,1,0,0,0
access_asset_multi_operation_manager,account.asset.multi.operation,model_account_asset_multi_operation,account.group_account_manager,1,1,1,1
access_asset_state_operation_manager,account.state.multi.operation,model_asset_states,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_asset_operation account.asset.operation model_account_asset_operation account.group_account_readonly 1 0 0 0
3 access_asset_operation_manager account.asset.operation model_account_asset_operation account.group_account_manager 1 1 1 1
4 access_asset_multi_operation account.asset.multi.operation model_account_asset_multi_operation account.group_account_readonly 1 0 0 0
5 access_asset_multi_operation_manager account.asset.multi.operation model_account_asset_multi_operation account.group_account_manager 1 1 1 1
6 access_asset_state_operation_manager account.state.multi.operation model_asset_states 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="asset_adjustment_form">
<field name="name">account.asset.adjustment.form</field>
<field name="model">account.asset.adjustment</field>
<field name="inherit_id" ref="exp_asset_base.asset_adjustment_form"/>
<field name="arch" type="xml">
<field name="model_id" position="after">
<field name="department_id"
invisible="type != 'department'"
required="type != 'department'"/>
<field name="employee_id"
invisible="type != 'employee'"
required="type == 'employee'"/>
<field name="location_id"
invisible="type != 'location'"
required="type == 'location'"
/>
</field>
</field>
</record>
</odoo>

View File

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Asset Custody Multi Operation -->
<record model="ir.ui.view" id="view_account_asset_multi_operation_tree">
<field name="name">account.asset.multi.operation.tree</field>
<field name="model">account.asset.multi.operation</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="date"/>
<field name="type"/>
<field name="responsible_user_id"/>
<field name="note"/>
<field name="state"/>
</list>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_multi_assignment_form">
<field name="name">account.asset.multi.assignment.form</field>
<field name="model">account.asset.multi.operation</field>
<field name="arch" type="xml">
<form duplicate="0">
<header>
<button name="act_progress" invisible="state != 'draft'" string="Start" type="object" class="oe_highlight"/>
<button name="act_confirm" groups='exp_asset_base.group_assets_manager' invisible="state != 'in_progress'" string="Confirm" type="object"
class="oe_highlight"/>
<button name="act_reject" groups="exp_asset_base.group_assets_manager" invisible="state != 'in_progress'" string="Reject" type="object"/>
<button name="act_draft" groups="exp_asset_base.group_assets_manager" invisible="state != 'cancel'" string="Set to Draft" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,done"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="barcode" nolabel="1" placeholder="Barcode..."/>
</h1>
</div>
<group>
<group>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="responsible_department_id" readonly="1"/>
<field name="manual" readonly="1"/>
</group>
<group>
<field name="type" invisible="1"/>
<field name="responsible_user_id"/>
<field name="note"/>
</group>
</group>
<group string="Assignment Info">
<group>
<field name="new_location_id"/>
<field name="new_employee_id"/>
<field name="new_department_id"/>
</group>
</group>
<notebook colspan="4">
<page string="Assets Assignment">
<field name="operation_ids" nolabel="1"
context="{'default_user_id':responsible_user_id, 'default_type':type, 'default_date':date,
'default_note':note, 'default_new_employee_id':new_employee_id,
'default_new_department_id':new_department_id, 'default_new_location_id':new_location_id}">
<list editable="top">
<field name="asset_id" required="1"
domain="[('status', 'in', ['new','available']), ('asset_type', '=', 'purchase'),
('state', '!=', 'model'), ('parent_id', '=', False)]"/>
<field name="custody_type" required="1"/>
<field name="custody_period" required="1"/>
<field name="return_date"
readonly="custody_period != 'temporary'"
required="custody_period == 'temporary'"/>
<field name="new_employee_id" invisible="1"/>
<field name="new_department_id" invisible="1"/>
<field name="new_location_id" invisible="1"/>
<field name="date" invisible="1"/>
<field name="type" invisible="1"/>
<field name="note" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="department_id" invisible="1"/>
<field name="state" invisible="1"/>
</list>
</field>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_multi_release_form">
<field name="name">account.asset.multi.release.form</field>
<field name="model">account.asset.multi.operation</field>
<field name="arch" type="xml">
<form duplicate="0">
<header>
<button name="act_progress" invisible="state != 'draft'" string="Start" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_confirm" invisible="state != 'in_progress'" string="Confirm" type="object"
class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_reject" invisible="state != 'in_progress'" string="Reject" type="object"/>
<button groups="exp_asset_base.group_assets_manager" name="act_draft" invisible="state != 'cancel'" string="Set to Draft" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,done"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="_barcode_scanned" widget="barcode_handler"/>
<field name="barcode" nolabel="1" placeholder="Barcode..."/>
</h1>
</div>
<group>
<group>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="responsible_department_id" readonly="1"/>
<field name="manual" readonly="1"/>
</group>
<group>
<field name="type" invisible="1"/>
<field name="responsible_user_id"/>
<field name="note"/>
</group>
</group>
<group>
<group string="Release Info">
<field name="new_location_id" string="Release Location" required="1"/>
</group>
</group>
<notebook colspan="4">
<page string="Assets Release">
<field name="operation_ids" nolabel="1"
context="{'default_user_id':responsible_user_id, 'default_type':type, 'default_date':date,
'default_note':note, 'default_new_location_id':new_location_id}">
<list editable="top">
<field name="asset_id" required="1"
domain="[('status', 'in', ['assigned']), ('asset_type', '=', 'purchase'),
('state', '!=', 'model'), ('parent_id', '=', False)]"/>
<field name="current_employee_id"/>
<field name="current_department_id"/>
<field name="current_location_id"/>
<field name="asset_status2"/>
<field name="new_employee_id" invisible="1"/>
<field name="new_department_id" invisible="1"/>
<field name="new_location_id" invisible="1"/>
<field name="date" invisible="1"/>
<field name="type" invisible="1"/>
<field name="note" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="department_id" invisible="1"/>
<field name="state" invisible="1"/>
</list>
</field>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_multi_transfer_form">
<field name="name">account.asset.multi.transfer.form</field>
<field name="model">account.asset.multi.operation</field>
<field name="arch" type="xml">
<form duplicate="0">
<header>
<button name="act_progress" invisible="state != 'draft'" string="Start" type="object" class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_confirm" invisible="state != 'in_progress'" string="Confirm" type="object"
class="oe_highlight"/>
<button groups="exp_asset_base.group_assets_manager" name="act_reject" invisible="state != 'in_progress'" string="Reject" type="object"/>
<button groups="exp_asset_base.group_assets_manager" name="act_draft" invisible="state != 'cancel'" string="Set to Draft" type="object" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,done"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="barcode" nolabel="1" placeholder="Barcode..."/>
</h1>
</div>
<group>
<group>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="responsible_department_id" readonly="1"/>
<field name="manual" readonly="1"/>
</group>
<group>
<field name="type" invisible="1"/>
<field name="responsible_user_id"/>
<field name="note"/>
</group>
</group>
<group invisible="type != 'transfer'" >
<group string="New">
<field name="new_employee_id"/>
<field name="new_department_id"/>
<field name="new_location_id"/>
</group>
</group>
<notebook colspan="4">
<page string="Assets Transfer">
<field name="operation_ids" nolabel="1"
context="{'default_user_id':responsible_user_id, 'default_type':type, 'default_date':date,
'default_note':note, 'default_new_employee_id':new_employee_id,
'default_new_department_id':new_department_id, 'default_new_location_id':new_location_id}">
<list editable="top">
<field name="asset_id" required="1"
domain="[('status', 'in', ['assigned']), ('asset_type', '=', 'purchase'),
('state', '!=', 'model'), ('parent_id', '=', False)]"/>
<field name="current_employee_id"/>
<field name="current_department_id"/>
<field name="current_location_id"/>
<field name="custody_type" required="1"/>
<field name="custody_period" required="1"/>
<field name="return_date"
required="custody_period == 'temporary'"
readonly="custody_period != 'temporary'"/>
<field name="new_employee_id" invisible="1"/>
<field name="new_department_id" invisible="1"/>
<field name="new_location_id" invisible="1"/>
<field name="date" invisible="1"/>
<field name="type" invisible="1"/>
<field name="note" invisible="1"/>
<field name="user_id" invisible="1"/>
<field name="department_id" invisible="1"/>
<field name="state" invisible="1"/>
</list>
</field>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record id="action_multi_asset_assignment" model="ir.actions.act_window">
<field name="name">Multiple Assignment</field>
<field name="res_model">account.asset.multi.operation</field>
<field name="view_mode">list,form</field>
<field name="context">{'default_manual':1, 'default_type':'assignment'}</field>
<field name="domain">[('type','=','assignment')]</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'list'}),
(0, 0, {'view_mode': 'form', 'view_id': ref('view_account_asset_multi_assignment_form')})]"/>
</record>
<record id="action_multi_asset_release" model="ir.actions.act_window">
<field name="name">Multiple Release</field>
<field name="res_model">account.asset.multi.operation</field>
<field name="view_mode">list,form</field>
<field name="context">{'default_manual':1, 'default_type':'release'}</field>
<field name="domain">[('type','=','release')]</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'list'}),
(0, 0, {'view_mode': 'form', 'view_id': ref('view_account_asset_multi_release_form')})]"/>
</record>
<record id="action_multi_asset_transfer" model="ir.actions.act_window">
<field name="name">Multiple Transfer</field>
<field name="res_model">account.asset.multi.operation</field>
<field name="view_mode">list,form</field>
<field name="context">{'default_manual':1, 'default_type':'transfer'}</field>
<field name="domain">[('type','=','transfer')]</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'list'}),
(0, 0, {'view_mode': 'form', 'view_id': ref('view_account_asset_multi_transfer_form')})]"/>
</record>
</odoo>

View File

@ -0,0 +1,337 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Asset Operations -->
<record id="view_account_asset_operation_search" model="ir.ui.view">
<field name="name">account.asset.operation.search</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<search string="Asset Account">
<field name="barcode"/>
<field name="asset_id"/>
<field name="model_id"/>
<field name="user_id"/>
<field name="department_id"/>
<field name="new_location_id"/>
<field name="new_employee_id"/>
<field name="new_department_id"/>
<field name="type"/>
<field name="date"/>
<field name="asset_statuso" invisible="1"/>
<filter string="Done" name="done" domain="[('state','=', 'done')]"
help="Asset Operations in done state"/>
<group expand="0" string="Group By...">
<filter string="Barcode" name="group_by_barcode" context="{'group_by':'barcode'}"/>
<filter string="Asset" name="group_by_asset" context="{'group_by':'asset_id'}"/>
<filter string="Model" name="group_by_model" context="{'group_by':'model_id'}"/>
<filter string="Responsible User" name="group_by_user" context="{'group_by':'user_id'}"/>
<filter string="Responsible Department" name="group_by_department"
context="{'group_by': 'department_id'}"/>
<filter string="Location" name="group_by_location" context="{'group_by':'new_location_id'}"/>
<filter string="Employee" name="group_by_employee" context="{'group_by':'new_employee_id'}"/>
<filter string="Department" name="group_by_department" context="{'group_by':'new_department_id'}"/>
<filter string="Type" name="group_by_type" context="{'group_by': 'type'}"/>
<filter string="Date" name="group_by_date" context="{'group_by': 'date'}"/>
<filter string="State" name="group_by_state" context="{'group_by':'state'}"/>
</group>
</search>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_operation_tree">
<field name="name">account.asset.operation.tree</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<list>
<field name="name"/>
<field name="type"/>
<field name="date"/>
<field name="asset_id"/>
<field name="barcode"/>
<field name="state"/>
</list>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_operation_form">
<field name="name">account.asset.operation.form</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<form duplicate="0">
<header>
<button name="act_submit" string="Submit" type="object"
class="oe_highlight" invisible="state != 'draft'"/>
<button name="act_confirm" groups='exp_asset_base.group_assets_manager' string="Confirm" invisible="state != 'submit'"
type="object" class="oe_highlight"/>
<button name="act_reject" groups="exp_asset_base.group_assets_manager" string="Reject" type="object" invisible="state != 'draft'" />
<button name="act_draft" groups="exp_asset_base.group_assets_manager" invisible="state != 'cancel'" string="Set to Draft"
type="object" class="oe_highlight"/>
<field name="state" widget="statusbar"/>
</header>
<sheet>
<div class="oe_title">
<h1>
<field name="type" readonly="1"/>
-
<field name="name" readonly="1"/>
</h1>
</div>
<group>
<group>
<field name="date"/>
<field name="user_id"/>
</group>
<group>
<field name="product_id" invisible="1"/>
<field name="asset_id"
required="type not in ['assignment', 'release']"
readonly="state not in ['draft', 'submit']"
domain="[('asset_type', '=', 'purchase'),
('status', 'in', {'receive': ['new'], 'assignment': ['new','available'], 'release': ['assigned'], 'transfer': ['assigned']}.get(type, ['new', 'available', 'assigned', 'scrap']))]"/>
<field name="department_id" readonly="1"/>
</group>
</group>
<group string="Assignment Info" invisible="type != 'assignment'" >
<group>
<field name="custody_type" required="type == 'assignment'" />
<field name="custody_period" required="type == 'assignment'" />
<field name="return_date"
invisible="custody_period != 'temporary'"
readonly="state != 'draft' or custody_period != 'temporary'"
/>
</group>
<group>
<field name="new_location_id"/>
<field name="new_employee_id"
required="custody_type == 'personal'"
/>
<field name="new_department_id"
required="custody_type == 'general'"
/>
</group>
</group>
<group invisible="type != 'release'" >
<group string="Current Info">
<field name="current_employee_id" force_save="1"/>
<field name="current_department_id" force_save="1"/>
<field name="current_location_id" force_save="1"/>
</group>
<group string="Release Info">
<field name="new_location_id" string="Release Location"
required="type != 'release'"/>
<field name="asset_status2" required="type == 'release'" />
<field name="asset_status" invisible="1"/>
<field name="amount" groups="exp_asset_base.group_asset_assessment"/>
</group>
</group>
<group
invisible="type != 'transfer'"
>
<group>
<field name="custody_type" required="type == 'transfer'" />
</group>
<group>
</group>
<group string="Current">
<field name="current_employee_id" readonly="1" force_save="1"/>
<field name="current_department_id" readonly="1" force_save="1"/>
<field name="current_location_id" readonly="1" force_save="1"/>
</group>
<group string="New">
<field name="new_employee_id"
required="custody_type == 'personal'"
/>
<field name="new_department_id"
required="custody_type == 'general'"/>
<field name="new_location_id"/>
</group>
</group>
<notebook colspan="4">
<page string="Note">
<field name="note" nolabel="1"/>
</page>
</notebook>
</sheet>
<chatter/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_assignment_tree">
<field name="name">account.asset.assignment.tree</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<list>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="product_id"/>
<field name="asset_id"
required="state != 'draft'"
readonly="state != 'submit'"
domain="[('status', 'in', ['new','available']),('asset_type', '=', 'purchase')]"/>
<field name="type" invisible="1"/>
<field name="custody_type" required="1"/>
<field name="custody_period" required="1"/>
<field name="return_date"
required="custody_period == 'temporary'"
readonly="state != 'draft' or custody_period != 'temporary'"
/>
<field name="new_location_id"/>
<field name="new_employee_id"
required="custody_type == 'personal'"
/>
<field name="new_department_id"
required="custody_type == 'general'"/>
<field name="state" readonly="1"/>
<!-- <button name="act_submit" states="draft" string="Submit" type="object" class="oe_highlight"/>-->
<!-- <button name="act_confirm" states="submit" string="Confirm" type="object" class="oe_highlight"/>-->
<!-- <button name="act_cancel" states="done" string="Cancel" type="object"/>-->
<!-- <button name="act_draft" states="cancel" string="Set to Draft" type="object"/>-->
<!-- <button name="action_read_operation" type="object" string="Setup" class="float-right btn-secondary"/>-->
</list>
</field>
</record>
<record id="action_account_asset_assignment" model="ir.actions.act_window">
<field name="name">Assets Assignment</field>
<field name="res_model">account.asset.operation</field>
<field name="view_mode">list,form</field>
<!-- <field name="view_id" ref="view_account_asset_assignment_tree"/>-->
<field name="context">
{'default_type': 'assignment', 'default_custody_type': 'personal', 'default_custody_period': 'permanent'}
</field>
<field name="domain">[('type', '=', 'assignment')]</field>
</record>
<record model="ir.ui.view" id="view_account_asset_release_tree">
<field name="name">account.asset.release.tree</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<list>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="asset_id" required="1"
readonly="state != 'draft'"
domain="[('status', 'in', ['assigned']),('asset_type', '=', 'purchase')]"/>
<field name="type" invisible="1"/>
<field name="current_employee_id" readonly="1" force_save="1"/>
<field name="current_department_id" readonly="1" force_save="1"/>
<field name="current_location_id" readonly="1" force_save="1"/>
<field name="new_location_id" string="Release Location" required="1"/>
<field name="asset_status2"/><field name="asset_status" invisible="1"/>
<field name="amount" groups="exp_asset_base.group_asset_assessment"/>
<field name="state" readonly="1"/>
<!-- <button name="act_confirm" states="draft" string="Confirm" type="object" class="oe_highlight"/>-->
<!-- <button name="act_cancel" states="done" string="Cancel" type="object"/>-->
<!-- <button name="act_draft" states="cancel" string="Set to Draft" type="object"/>-->
<!-- <button name="action_read_operation" type="object" string="Setup" class="float-right btn-secondary"/>-->
</list>
</field>
</record>
<record id="action_account_asset_release" model="ir.actions.act_window">
<field name="name">Assets Release</field>
<field name="res_model">account.asset.operation</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="view_account_asset_release_tree"/>
<field name="context">{'default_type': 'release'}</field>
<field name="domain">[('type', '=', 'release')]</field>
</record>
<record model="ir.ui.view" id="view_account_asset_transfer_tree">
<field name="name">account.asset.transfer.tree</field>
<field name="model">account.asset.operation</field>
<field name="arch" type="xml">
<list>
<field name="name" readonly="1"/>
<field name="date"/>
<field name="asset_id" required="1"
readonly="state != 'draft'"
domain="[('status', 'in', ['assigned']),('asset_type', '=', 'purchase')]"/>
<field name="type" invisible="1"/>
<field name="current_employee_id" readonly="1" force_save="1"/>
<field name="current_department_id" readonly="1" force_save="1"/>
<field name="current_location_id" readonly="1" force_save="1"/>
<field name="custody_type" required="1"/>
<field name="custody_period" required="1"/>
<field name="return_date"
required="custody_period == 'temporary'"
readonly="state != 'draft' or custody_period != 'temporary'"
/>
<field name="new_location_id" string="New Location"/>
<field name="new_employee_id" string="New Employee"
required="custody_type == 'personal'"/>
<field name="new_department_id" string="New Department"
required="custody_type == 'general'"/>
<field name="state" readonly="1"/>
<!-- <button name="act_confirm" states="draft" string="Confirm" type="object" class="oe_highlight"/>-->
<!-- <button name="act_cancel" states="done" string="Cancel" type="object"/>-->
<!-- <button name="act_draft" states="cancel" string="Set to Draft" type="object"/>-->
<!-- <button name="action_read_operation" type="object" string="Setup" class="float-right btn-secondary"/>-->
</list>
</field>
</record>
<record id="action_account_asset_transfer" model="ir.actions.act_window">
<field name="name">Assets Transfer</field>
<field name="res_model">account.asset.operation</field>
<field name="view_mode">list,form</field>
<field name="view_id" ref="view_account_asset_transfer_tree"/>
<field name="context">{'default_type': 'transfer'}</field>
<field name="domain">[('type', '=', 'transfer')]</field>
</record>
<!-- Operation Analysis -->
<record id="action_account_asset_operation_analysis" model="ir.actions.act_window">
<field name="name">Operation Analysis</field>
<field name="view_mode">graph,pivot,list</field>
<field name="search_view_id" ref="view_account_asset_operation_search"/>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'graph'}),
(0, 0, {'view_mode': 'pivot'}),
(0, 0, {'view_mode': 'list', 'view_id': ref('view_account_asset_operation_tree')})]"/>
<field name="res_model">account.asset.operation</field>
<field name="context">{'search_default_group_by_type': True}</field>
</record>
<record id="asset_operation_view_form3" model="ir.ui.view">
<field name="name">asset_operation_form3.extend</field>
<field name="model">account.asset.multi.operation</field>
<field name="inherit_id" ref="exp_asset_custody.view_account_asset_multi_transfer_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='act_confirm']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='act_reject']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='act_draft']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
</field>
</record>
<record id="asset_operation_view_form5" model="ir.ui.view">
<field name="name">asset_operation_form5.extend</field>
<field name="model">account.asset.operation</field>
<field name="inherit_id" ref="exp_asset_custody.view_account_asset_operation_form"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='act_confirm']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='act_reject']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
<xpath expr="//button[@name='act_draft']" position="attributes">
<attribute name="groups">exp_asset_base.group_assets_manager</attribute>
</xpath>
</field>
</record>
</odoo>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Asset Register -->
<record id="view_account_asset_search" model="ir.ui.view">
<field name="name">account.asset.search</field>
<field name="model">account.asset</field>
<field name="inherit_id" ref="exp_asset_base.view_account_asset_search"/>
<field name="arch" type="xml">
<field name="analytic_distribution" position="after">
<field name="employee_id"/>
<field name="department_id"/>
<field name="location_id"/>
</field>
<filter name="cost_center" position="after">
<filter string="Employee" name="employee" domain="[]" context="{'group_by':'employee_id'}"/>
<filter string="Department" name="department" domain="[]" context="{'group_by':'department_id'}"/>
<filter string="Location" name="location" domain="[]" context="{'group_by':'location_id'}"/>
<filter string="Custody Type" name="custody_type" domain="[]" context="{'group_by':'custody_type'}"/>
</filter>
</field>
</record>
<record model="ir.ui.view" id="view_account_asset_form">
<field name="name">account.asset.form</field>
<field name="model">account.asset</field>
<field name="inherit_id" ref="odex30_account_asset.view_account_asset_form"/>
<field name="arch" type="xml">
<div name="button_box" position="inside">
<button class="oe_stat_button" name="open_asset_operation" type="object" icon="fa-pencil">
<field string="Operations" name="asset_operation_count" widget="statinfo"/>
</button>
</div>
<notebook position="before">
<group string="Custody Info" invisible="state != 'model' or asset_type != 'purchase'" >
<group>
<field name="custody_type" readonly="1"/>
<field name="purpose" readonly="1"/>
<field name="custody_period" readonly="1"/>
<field name="return_date" readonly="1"/>
</group>
<group>
<field name="status" readonly="1"/>
<field name="department_id" readonly="1"/>
<field name="employee_id" readonly="1"/>
<field name="location_id" readonly="1"/>
</group>
</group>
</notebook>
</field>
</record>
</odoo>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data>
<!-- Asset Operations -->
<menuitem id="menu_account_asset_operation_main"
parent="exp_asset_base.menu_account_asset_operation_main"
name="Custody Operations"
sequence="4"/>
<!-- Multi Operations -->
<menuitem id="menu_account_asset_multi_operation"
parent="menu_account_asset_operation_main"
name="Multiple operations"
sequence="1"/>
<menuitem id="menu_account_multi_asset_assignment"
parent="menu_account_asset_multi_operation"
action="action_multi_asset_assignment"
name="Assignment"
sequence="4"/>
<menuitem id="menu_account_multi_asset_release"
parent="menu_account_asset_multi_operation"
action="action_multi_asset_release"
name="Release"
sequence="5"/>
<menuitem id="menu_account_multi_asset_transfer"
parent="menu_account_asset_multi_operation"
action="action_multi_asset_transfer"
name="Transfer"
sequence="6"/>
<!-- Custody Operation -->
<menuitem id="menu_account_asset_custody_operation"
parent="menu_account_asset_operation_main"
name="Custody operations"
sequence="3"/>
<menuitem id="menu_account_asset_assignment"
parent="menu_account_asset_custody_operation"
action="action_account_asset_assignment"
name="Assignment"
sequence="1"/>
<menuitem id="menu_account_asset_release"
parent="menu_account_asset_custody_operation"
action="action_account_asset_release"
name="Release"
sequence="2"/>
<menuitem id="menu_account_asset_transfer"
parent="menu_account_asset_custody_operation"
action="action_account_asset_transfer"
name="Transfer"
sequence="3"/>
<menuitem id="menu_account_operation_graph"
parent="exp_asset_base.menu_account_asset_reporting_main"
action="action_account_asset_operation_analysis"
name="Operation Analysis"
sequence="3"/>
</data>
</odoo>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import models

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
{
'name': "HR Custody Integration With Asset Custody",
'summary': """
- Assign Asset as a custody to an employee
- Release Asset as a custody from an employee
""",
'version': '14.0',
'sequence': 4,
'category': 'Odex30-Accounting/Odex30-Accounting',
'website': 'http://exp-sa.com',
'license': 'AGPL-3',
'author': 'Expert Co. Ltd.',
'depends': ['exp_employee_custody','exp_asset_custody','purchase'],
# always loaded
'data': [
'security/ir.model.access.csv',
'views/employee_custody_action.xml',
],
}

Some files were not shown because too many files have changed in this diff Show More