[MERGE]merge with trunk
bzr revid: kbh@tinyerp.com-20121109052919-q1oo1us9il2jrqf4
This commit is contained in:
commit
d251e8e63f
|
@ -541,10 +541,18 @@ class account_account(osv.osv):
|
|||
return False
|
||||
return True
|
||||
|
||||
def _check_company_account(self, cr, uid, ids, context=None):
|
||||
for account in self.browse(cr, uid, ids, context=context):
|
||||
if account.parent_id:
|
||||
if account.company_id != account.parent_id.company_id:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error!\nYou cannot create recursive accounts.', ['parent_id']),
|
||||
(_check_type, 'Configuration Error!\nYou cannot define children to an account with internal type different of "View".', ['type']),
|
||||
(_check_account_type, 'Configuration Error!\nYou cannot select an account type with a deferral method different of "Unreconciled" for accounts with internal type "Payable/Receivable".', ['user_type','type']),
|
||||
(_check_company_account, 'Error!\nYou cannot create an account which has parent account of different company.', ['parent_id']),
|
||||
]
|
||||
_sql_constraints = [
|
||||
('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
|
||||
|
|
|
@ -168,10 +168,8 @@
|
|||
context="{'default_customer': 0, 'search_default_supplier': 1, 'default_supplier': 1}"
|
||||
domain="[('supplier', '=', True)]"/>
|
||||
<field name="fiscal_position" widget="selection"/>
|
||||
<group>
|
||||
<field name="origin"/>
|
||||
<field name="supplier_invoice_number"/>
|
||||
</group>
|
||||
<field name="origin"/>
|
||||
<field name="supplier_invoice_number"/>
|
||||
<label for="reference_type"/>
|
||||
<div>
|
||||
<field name="reference_type" class="oe_inline oe_edit_only"/>
|
||||
|
|
|
@ -975,7 +975,7 @@ class account_move_line(osv.osv):
|
|||
if context is None:
|
||||
context = {}
|
||||
result = super(account_move_line, self).fields_view_get(cr, uid, view_id, view_type, context=context, toolbar=toolbar, submenu=submenu)
|
||||
if view_type != 'tree':
|
||||
if (view_type != 'tree') or view_id:
|
||||
#Remove the toolbar from the form view
|
||||
if view_type == 'form':
|
||||
if result.get('toolbar', False):
|
||||
|
|
|
@ -1791,7 +1791,7 @@
|
|||
<field name="name"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<field name="note" placeholder="Note fo the invoice..."/>
|
||||
<field name="note" placeholder="Note for the invoice..."/>
|
||||
<separator string="Computation"/>
|
||||
<field name="line_ids"/>
|
||||
</form>
|
||||
|
|
|
@ -127,7 +127,6 @@
|
|||
<field name="view_id" ref="account_journal_bank_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="bank_col20" model="account.journal.column">
|
||||
|
@ -215,7 +214,6 @@
|
|||
<field name="view_id" ref="account_journal_bank_view_multi"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="bank_col20_multi" model="account.journal.column">
|
||||
|
@ -291,7 +289,6 @@
|
|||
<field name="view_id" ref="account_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
|
||||
|
@ -373,7 +370,6 @@
|
|||
<field name="view_id" ref="account_sp_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="sp_journal_col20" model="account.journal.column">
|
||||
|
@ -460,7 +456,6 @@
|
|||
<field name="view_id" ref="account_sp_refund_journal_view"/>
|
||||
<field name="name">Status</field>
|
||||
<field name="field">state</field>
|
||||
<field eval="True" name="invisible"/>
|
||||
<field eval="19" name="sequence"/>
|
||||
</record>
|
||||
<record id="sp_refund_journal_col20" model="account.journal.column">
|
||||
|
|
|
@ -48,7 +48,7 @@ openerp.account = function (instance) {
|
|||
this.last_group_by = group_by;
|
||||
this.old_search = _.bind(this._super, this);
|
||||
var mod = new instance.web.Model("account.move.line", context, domain);
|
||||
return mod.call("list_partners_to_reconcile", []).pipe(function(result) {
|
||||
return mod.call("list_partners_to_reconcile", []).then(function(result) {
|
||||
var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null;
|
||||
self.partners = result;
|
||||
var index = _.find(_.range(self.partners.length), function(el) {
|
||||
|
@ -74,7 +74,7 @@ openerp.account = function (instance) {
|
|||
return fct();
|
||||
} else {
|
||||
return new instance.web.Model("res.partner").call("read",
|
||||
[self.partners[self.current_partner][0], ["last_reconciliation_date"]]).pipe(function(res) {
|
||||
[self.partners[self.current_partner][0], ["last_reconciliation_date"]]).then(function(res) {
|
||||
self.last_reconciliation_date =
|
||||
instance.web.format_value(res.last_reconciliation_date, {"type": "datetime"}, _t("Never"));
|
||||
return fct();
|
||||
|
@ -92,7 +92,7 @@ openerp.account = function (instance) {
|
|||
return false;
|
||||
}
|
||||
|
||||
new instance.web.Model("ir.model.data").call("get_object_reference", ["account", "action_view_account_move_line_reconcile"]).pipe(function(result) {
|
||||
new instance.web.Model("ir.model.data").call("get_object_reference", ["account", "action_view_account_move_line_reconcile"]).then(function(result) {
|
||||
var additional_context = _.extend({
|
||||
active_id: ids[0],
|
||||
active_ids: ids,
|
||||
|
@ -101,7 +101,7 @@ openerp.account = function (instance) {
|
|||
return self.rpc("/web/action/load", {
|
||||
action_id: result[1],
|
||||
context: additional_context
|
||||
}).then(function (result) {
|
||||
}).done(function (result) {
|
||||
result.context = _.extend(result.context || {}, additional_context);
|
||||
result.flags = result.flags || {};
|
||||
result.flags.new_window = true;
|
||||
|
@ -116,7 +116,7 @@ openerp.account = function (instance) {
|
|||
mark_as_reconciled: function() {
|
||||
var self = this;
|
||||
var id = self.partners[self.current_partner][0];
|
||||
new instance.web.Model("res.partner").call("mark_as_reconciled", [[id]]).pipe(function() {
|
||||
new instance.web.Model("res.partner").call("mark_as_reconciled", [[id]]).then(function() {
|
||||
self.do_search(self.last_domain, self.last_context, self.last_group_by);
|
||||
});
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -712,14 +712,14 @@ class account_voucher(osv.osv):
|
|||
'move_line_id':line.id,
|
||||
'account_id':line.account_id.id,
|
||||
'amount_original': amount_original,
|
||||
'amount': (move_line_found == line.id) and min(price, amount_unreconciled) or 0.0,
|
||||
'amount': (move_line_found == line.id) and min(abs(price), amount_unreconciled) or 0.0,
|
||||
'date_original':line.date,
|
||||
'date_due':line.date_maturity,
|
||||
'amount_unreconciled': amount_unreconciled,
|
||||
'currency_id': line_currency_id,
|
||||
}
|
||||
|
||||
#split voucher amount by most old first, but only for lines in the same currency
|
||||
#in case a corresponding move_line hasn't been found, we now try to assign the voucher amount
|
||||
#on existing invoices: we split voucher amount by most old first, but only for lines in the same currency
|
||||
if not move_line_found:
|
||||
if currency_id == line_currency_id:
|
||||
if line.credit:
|
||||
|
|
|
@ -7,14 +7,15 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:37+0100\n"
|
||||
"PO-Revision-Date: 2012-05-10 17:31+0000\n"
|
||||
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
|
||||
"PO-Revision-Date: 2012-11-07 13:27+0000\n"
|
||||
"Last-Translator: Frederic Clementi - Camptocamp.com "
|
||||
"<frederic.clementi@camptocamp.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-30 05:19+0000\n"
|
||||
"X-Generator: Launchpad (build 16206)\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-08 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16232)\n"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:sale.receipt.report:0
|
||||
|
@ -469,7 +470,7 @@ msgstr "Délai moyen de règlement"
|
|||
#. module: account_voucher
|
||||
#: field:res.company,income_currency_exchange_account_id:0
|
||||
msgid "Income Currency Rate"
|
||||
msgstr "Taux de change d'achat"
|
||||
msgstr "Compte de gain de change"
|
||||
|
||||
#. module: account_voucher
|
||||
#: code:addons/account_voucher/account_voucher.py:1063
|
||||
|
@ -625,9 +626,9 @@ msgid ""
|
|||
"Unable to create accounting entry for currency rate difference. You have to "
|
||||
"configure the field 'Income Currency Rate' on the company! "
|
||||
msgstr ""
|
||||
"Impossible de créer une entrée de la comptabilité à cause de la différence "
|
||||
"de taux de change. Vous devez configurer le champ 'Taux de change de vente' "
|
||||
"sur la société! "
|
||||
"Impossible de créer une écriture comptable à cause de la différence de taux "
|
||||
"de change. Vous devez configurer le champ 'Compte de gain de change' au "
|
||||
"niveau du formulaire de la société! "
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0 view:sale.receipt.report:0
|
||||
|
@ -802,7 +803,7 @@ msgstr "Factures et transactions exceptionnelles"
|
|||
#. module: account_voucher
|
||||
#: field:res.company,expense_currency_exchange_account_id:0
|
||||
msgid "Expense Currency Rate"
|
||||
msgstr "Taux de change de la dépense"
|
||||
msgstr "Compte de perte de change"
|
||||
|
||||
#. module: account_voucher
|
||||
#: sql_constraint:account.invoice:0
|
||||
|
@ -1089,9 +1090,9 @@ msgid ""
|
|||
"Unable to create accounting entry for currency rate difference. You have to "
|
||||
"configure the field 'Expense Currency Rate' on the company! "
|
||||
msgstr ""
|
||||
"Impossible de créer une entrée en comptabilité pour la différence de taux de "
|
||||
"change. Vous devez configurer le champ \"Taux de change d'achat\" de la "
|
||||
"société ! "
|
||||
"Impossible de créer une écriture comptable à cause de la différence de taux "
|
||||
"de change. Vous devez configurer le champ 'Compte de perte de change' au "
|
||||
"niveau du formulaire de la société! "
|
||||
|
||||
#. module: account_voucher
|
||||
#: field:account.voucher,type:0
|
||||
|
@ -1156,7 +1157,7 @@ msgstr "Année"
|
|||
#. module: account_voucher
|
||||
#: field:account.voucher.line,amount_unreconciled:0
|
||||
msgid "Open Balance"
|
||||
msgstr "Solde initial"
|
||||
msgstr "Restant dû"
|
||||
|
||||
#. module: account_voucher
|
||||
#: view:account.voucher:0 field:account.voucher,amount:0
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
Once the end date of the contract is
|
||||
passed or the maximum number of service
|
||||
units (e.g. support contract) is
|
||||
reached, the account manager is warned
|
||||
reached, the account manager is notified
|
||||
by email to renew the contract with the
|
||||
customer.
|
||||
</p>
|
||||
|
|
|
@ -3,7 +3,7 @@ openerp.auth_anonymous = function(instance) {
|
|||
instance.web.Login.include({
|
||||
start: function() {
|
||||
var self = this;
|
||||
return $.when(this._super()).pipe(function() {
|
||||
return $.when(this._super()).then(function() {
|
||||
var dblist = self._db_list || [];
|
||||
if (!self.session.session_is_valid() && dblist.length === 1) {
|
||||
self.remember_credentials = false;
|
||||
|
|
|
@ -12,7 +12,7 @@ openerp.auth_oauth = function(instance) {
|
|||
} else if(this.params.oauth_error === 2) {
|
||||
this.do_warn("Authentication error","");
|
||||
}
|
||||
return d.then(this.do_oauth_load).fail(function() {
|
||||
return d.done(this.do_oauth_load).fail(function() {
|
||||
self.do_oauth_load([]);
|
||||
});
|
||||
},
|
||||
|
@ -23,7 +23,7 @@ openerp.auth_oauth = function(instance) {
|
|||
do_oauth_load: function() {
|
||||
var db = this.$("form [name=db]").val();
|
||||
if (db) {
|
||||
this.rpc("/auth_oauth/list_providers", { dbname: db }).then(this.on_oauth_loaded);
|
||||
this.rpc("/auth_oauth/list_providers", { dbname: db }).done(this.on_oauth_loaded);
|
||||
}
|
||||
},
|
||||
on_oauth_loaded: function(result) {
|
||||
|
|
|
@ -69,7 +69,7 @@ instance.web.Login = instance.web.Login.extend({
|
|||
_check_error: function() {
|
||||
var self = this;
|
||||
if (this.params.loginerror !== undefined) {
|
||||
this.rpc('/auth_openid/login/status', {}).then(function(result) {
|
||||
this.rpc('/auth_openid/login/status', {}).done(function(result) {
|
||||
if (_.contains(['success', 'failure'], result.status) && result.message) {
|
||||
self.do_warn('Invalid OpenID Login', result.message);
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ instance.web.Login = instance.web.Login.extend({
|
|||
|
||||
do_openid_login: function(db, openid_url) {
|
||||
var self = this;
|
||||
this.rpc('/auth_openid/login/verify', {'db': db, 'url': openid_url}).then(function(result) {
|
||||
this.rpc('/auth_openid/login/verify', {'db': db, 'url': openid_url}).done(function(result) {
|
||||
if (result.error) {
|
||||
self.do_warn(result.title, result.error);
|
||||
return;
|
||||
|
|
|
@ -300,7 +300,7 @@ trigger date, like sending a reminder 15 minutes before a meeting."),
|
|||
write['date_action_last'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if hasattr(obj, 'state') and action.act_state:
|
||||
write['state'] = action.act_state
|
||||
|
||||
|
||||
model_obj.write(cr, uid, [obj.id], write, context)
|
||||
if hasattr(obj, 'state') and hasattr(obj, 'message_post') and action.act_state:
|
||||
model_obj.message_post(cr, uid, [obj], _(action.act_state), context=context)
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="model" invisible="1"/>
|
||||
<field name="filter_id" domain="[('model_id','=',model)]" context="{'default_model_id': model}"/>
|
||||
<field name="sequence"/>
|
||||
<field name="active"/>
|
||||
<field name="model" invisible="1"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Conditions">
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_base_import_tests_models_char,base.import.tests.models.char,model_base_import_tests_models_char,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_char_required,base.import.tests.models.char.required,model_base_import_tests_models_char_required,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_char_readonly,base.import.tests.models.char.readonly,model_base_import_tests_models_char_readonly,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_char_states,base.import.tests.models.char.states,model_base_import_tests_models_char_states,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_char_noreadonly,base.import.tests.models.char.noreadonly,model_base_import_tests_models_char_noreadonly,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_char_stillreadonly,base.import.tests.models.char.stillreadonly,model_base_import_tests_models_char_stillreadonly,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_m2o,base.import.tests.models.m2o,model_base_import_tests_models_m2o,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_m2o_related,base.import.tests.models.m2o.related,model_base_import_tests_models_m2o_related,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_m2o_required,base.import.tests.models.m2o.required,model_base_import_tests_models_m2o_required,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_m2o_required_related,base.import.tests.models.m2o.required.related,model_base_import_tests_models_m2o_required_related,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_o2m,base.import.tests.models.o2m,model_base_import_tests_models_o2m,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_o2m_child,base.import.tests.models.o2m.child,model_base_import_tests_models_o2m_child,base.group_user,1,1,1,1
|
||||
access_base_import_tests_models_preview,base.import.tests.models.preview,model_base_import_tests_models_preview,base.group_user,1,1,1,1
|
||||
|
|
|
@ -123,10 +123,10 @@ openerp.base_import = function (instance) {
|
|||
this.exit();
|
||||
}
|
||||
},
|
||||
init: function (parent, params) {
|
||||
init: function (parent, action) {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
this.res_model = params.model;
|
||||
this.res_model = action.params.model;
|
||||
// import object id
|
||||
this.id = null;
|
||||
this.Import = new instance.web.Model('base_import.import');
|
||||
|
@ -139,7 +139,7 @@ openerp.base_import = function (instance) {
|
|||
this._super(),
|
||||
this.Import.call('create', [{
|
||||
'res_model': this.res_model
|
||||
}]).then(function (id) {
|
||||
}]).done(function (id) {
|
||||
self.id = id;
|
||||
self.$('input[name=import_id]').val(id);
|
||||
})
|
||||
|
@ -179,7 +179,8 @@ openerp.base_import = function (instance) {
|
|||
|
||||
//- File & settings change section
|
||||
onfile_loaded: function () {
|
||||
this.$('.oe_import_button').prop('disabled', true);
|
||||
this.$('.oe_import_button, .oe_import_file_reload')
|
||||
.prop('disabled', true);
|
||||
if (!this.$('input.oe_import_file').val()) { return; }
|
||||
|
||||
this.$el.removeClass('oe_import_preview oe_import_error');
|
||||
|
@ -189,7 +190,8 @@ openerp.base_import = function (instance) {
|
|||
},
|
||||
onpreviewing: function () {
|
||||
var self = this;
|
||||
this.$('.oe_import_button').prop('disabled', true);
|
||||
this.$('.oe_import_button, .oe_import_file_reload')
|
||||
.prop('disabled', true);
|
||||
this.$el.addClass('oe_import_with_file');
|
||||
// TODO: test that write // succeeded?
|
||||
this.$el.removeClass('oe_import_preview_error oe_import_error');
|
||||
|
@ -198,13 +200,14 @@ openerp.base_import = function (instance) {
|
|||
!this.$('input.oe_import_has_header').prop('checked'));
|
||||
this.Import.call(
|
||||
'parse_preview', [this.id, this.import_options()])
|
||||
.then(function (result) {
|
||||
.done(function (result) {
|
||||
var signal = result.error ? 'preview_failed' : 'preview_succeeded';
|
||||
self[signal](result);
|
||||
});
|
||||
},
|
||||
onpreview_error: function (event, from, to, result) {
|
||||
this.$('.oe_import_options').show();
|
||||
this.$('.oe_import_file_reload').prop('disabled', false);
|
||||
this.$el.addClass('oe_import_preview_error oe_import_error');
|
||||
this.$('.oe_import_error_report').html(
|
||||
QWeb.render('ImportView.preview.error', result));
|
||||
|
@ -212,7 +215,8 @@ openerp.base_import = function (instance) {
|
|||
onpreview_success: function (event, from, to, result) {
|
||||
this.$('.oe_import_import').removeClass('oe_highlight');
|
||||
this.$('.oe_import_validate').addClass('oe_highlight');
|
||||
this.$('.oe_import_button').prop('disabled', false);
|
||||
this.$('.oe_import_button, .oe_import_file_reload')
|
||||
.prop('disabled', false);
|
||||
this.$el.addClass('oe_import_preview');
|
||||
this.$('table').html(QWeb.render('ImportView.preview', result));
|
||||
|
||||
|
@ -337,11 +341,11 @@ openerp.base_import = function (instance) {
|
|||
},
|
||||
onvalidate: function () {
|
||||
return this.call_import({ dryrun: true })
|
||||
.then(this.proxy('validated'));
|
||||
.done(this.proxy('validated'));
|
||||
},
|
||||
onimport: function () {
|
||||
var self = this;
|
||||
return this.call_import({ dryrun: false }).then(function (message) {
|
||||
return this.call_import({ dryrun: false }).done(function (message) {
|
||||
if (!_.any(message, function (message) {
|
||||
return message.type === 'error' })) {
|
||||
self['import_succeeded']();
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
<label t-attf-for="file_#{_id}" autofocus="autofocus">CSV File:</label>
|
||||
<input type="file" id-attf-id="file_#{_id}"
|
||||
name="file" class="oe_import_file"/>
|
||||
<button type="button" class="oe_import_file_reload" title="Reload data to check changes.">
|
||||
<button type="button" class="oe_import_file_reload"
|
||||
disabled="disabled"
|
||||
title="Reload data to check changes.">
|
||||
<img src="/web/static/src/img/icons/gtk-refresh.png"/>
|
||||
</button>
|
||||
<div class="oe_import_with_file">
|
||||
|
|
|
@ -60,14 +60,14 @@ class sale_config_settings(osv.osv_memory):
|
|||
'module_web_linkedin': fields.boolean('Get contacts automatically from linkedIn',
|
||||
help="""When you create a new contact (person or company), you will be able to load all the data from LinkedIn (photos, address, etc)."""),
|
||||
'module_crm': fields.boolean('CRM'),
|
||||
'module_plugin_thunderbird': fields.boolean('Enable Thunderbird plugin',
|
||||
'module_plugin_thunderbird': fields.boolean('Enable Thunderbird plug-in',
|
||||
help="""The plugin allows you archive email and its attachments to the selected
|
||||
OpenERP objects. You can select a partner, or a lead and
|
||||
attach the selected mail as a .eml file in
|
||||
the attachment of a selected record. You can create documents for CRM Lead,
|
||||
Partner from the selected emails.
|
||||
This installs the module plugin_thunderbird."""),
|
||||
'module_plugin_outlook': fields.boolean('Enable Outlook plugin',
|
||||
'module_plugin_outlook': fields.boolean('Enable Outlook plug-in',
|
||||
help="""The Outlook plugin allows you to select an object that you would like to add
|
||||
to your email and its attachments from MS Outlook. You can select a partner,
|
||||
or a lead object and archive a selected
|
||||
|
|
|
@ -46,7 +46,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
delete(action.attrs.colspan);
|
||||
var action_id = _.str.toNumber(action.attrs.name);
|
||||
if (!_.isNaN(action_id)) {
|
||||
self.rpc('/web/action/load', {action_id: action_id}).then(function(result) {
|
||||
self.rpc('/web/action/load', {action_id: action_id}).done(function(result) {
|
||||
self.on_load_action(result, column_index + '_' + action_index, action.attrs);
|
||||
});
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
this.rpc('/web/view/undo_custom', {
|
||||
view_id: this.view.fields_view.view_id,
|
||||
reset: true
|
||||
}).then(this.do_reload);
|
||||
}).done(this.do_reload);
|
||||
},
|
||||
on_change_layout: function() {
|
||||
var self = this;
|
||||
|
@ -242,7 +242,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
};
|
||||
var list = am.inner_widget.views.list;
|
||||
if (list) {
|
||||
list.deferred.then(function() {
|
||||
list.deferred.done(function() {
|
||||
$(list.controller.groups).off('row_link').on('row_link', function(e, id) {
|
||||
new_form_action(id);
|
||||
});
|
||||
|
@ -250,7 +250,7 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
|
|||
}
|
||||
var kanban = am.inner_widget.views.kanban;
|
||||
if (kanban) {
|
||||
kanban.deferred.then(function() {
|
||||
kanban.deferred.done(function() {
|
||||
kanban.controller.open_record = function(id, editable) {
|
||||
new_form_action(id, editable);
|
||||
};
|
||||
|
@ -335,7 +335,7 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({
|
|||
e.preventDefault();
|
||||
self.add_dashboard();
|
||||
});
|
||||
return this.load_data().then(this.proxy("render_data"));
|
||||
return this.load_data().done(this.proxy("render_data"));
|
||||
},
|
||||
load_data:function(){
|
||||
var board = new instance.web.Model('board.board');
|
||||
|
@ -347,7 +347,7 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({
|
|||
return new instance.web.Model('ir.model.data')
|
||||
.query(['res_id'])
|
||||
.filter([['name','=','menu_reporting_dashboard']])
|
||||
.first().pipe(function (result) {
|
||||
.first().then(function (result) {
|
||||
var menu = _(dashboard_menu).chain()
|
||||
.pluck('children')
|
||||
.flatten(true)
|
||||
|
@ -382,7 +382,7 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({
|
|||
domain: domain,
|
||||
view_mode: view_parent.active_view,
|
||||
name: this.$el.find("input").val()
|
||||
}).then(function(r) {
|
||||
}).done(function(r) {
|
||||
if (r === false) {
|
||||
self.do_warn("Could not add filter to dashboard");
|
||||
} else {
|
||||
|
|
|
@ -619,9 +619,9 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
}
|
||||
|
||||
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, section_id=False, context=None):
|
||||
partner = self.pool.get('res.partner')
|
||||
customer = False
|
||||
if partner_id:
|
||||
partner = self.pool.get('res.partner')
|
||||
customer = partner.browse(cr, uid, partner_id, context=context)
|
||||
for lead in self.browse(cr, uid, ids, context=context):
|
||||
if lead.state in ('done', 'cancel'):
|
||||
|
@ -685,19 +685,17 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
def convert_partner(self, cr, uid, ids, action='create', partner_id=False, context=None):
|
||||
"""
|
||||
This function convert partner based on action.
|
||||
Convert partner based on action.
|
||||
if action is 'create', create new partner with contact and assign lead to new partner_id.
|
||||
otherwise assign lead to specified partner_id
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
partner_ids = {}
|
||||
force_partner_id = partner_id
|
||||
for lead in self.browse(cr, uid, ids, context=context):
|
||||
if action == 'create':
|
||||
if not partner_id:
|
||||
partner_id = self._create_lead_partner(cr, uid, lead, context)
|
||||
partner_id = force_partner_id or self._create_lead_partner(cr, uid, lead, context=context)
|
||||
self._lead_set_partner(cr, uid, lead, partner_id, context=context)
|
||||
partner_ids[lead.id] = partner_id
|
||||
return partner_ids
|
||||
|
|
|
@ -56,6 +56,7 @@ added to partners that match the segmentation criterions after computation.'),
|
|||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Process continue’s IDs"""
|
||||
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
categs = self.read(cr, uid, ids, ['categ_id', 'exclusif', 'partner_id',\
|
||||
'sales_purchase_active', 'profiling_active'])
|
||||
for categ in categs:
|
||||
|
@ -80,9 +81,11 @@ added to partners that match the segmentation criterions after computation.'),
|
|||
for pid in to_remove_list:
|
||||
partners.remove(pid)
|
||||
|
||||
for partner_id in partners:
|
||||
cr.execute('insert into res_partner_res_partner_category_rel (category_id,partner_id) \
|
||||
values (%s,%s)', (categ['categ_id'][0], partner_id))
|
||||
for partner in partner_obj.browse(cr, uid, partners):
|
||||
category_ids = [categ_id.id for categ_id in partner.category_id]
|
||||
if categ['categ_id'][0] not in category_ids:
|
||||
cr.execute('insert into res_partner_res_partner_category_rel (category_id,partner_id) \
|
||||
values (%s,%s)', (categ['categ_id'][0], partner.id))
|
||||
|
||||
self.write(cr, uid, [id], {'state':'not running', 'partner_id':0})
|
||||
return True
|
||||
|
|
|
@ -175,12 +175,19 @@ class crm_lead2opportunity_mass_convert(osv.osv_memory):
|
|||
return res
|
||||
|
||||
def _convert_opportunity(self, cr, uid, ids, vals, context=None):
|
||||
"""
|
||||
When "massively" (more than one at a time) converting leads to
|
||||
opportunities, check the salesteam_id and salesmen_ids and update
|
||||
the values before calling super.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
data = self.browse(cr, uid, ids, context=context)[0]
|
||||
salesteam_id = data.section_id and data.section_id.id or False
|
||||
salesman = []
|
||||
salesmen_ids = []
|
||||
if data.user_ids:
|
||||
salesman = [x.id for x in data.user_ids]
|
||||
vals.update({'user_ids': salesman, 'section_id': salesteam_id})
|
||||
salesmen_ids = [x.id for x in data.user_ids]
|
||||
vals.update({'user_ids': salesmen_ids, 'section_id': salesteam_id})
|
||||
return super(crm_lead2opportunity_mass_convert, self)._convert_opportunity(cr, uid, ids, vals, context=context)
|
||||
|
||||
def mass_convert(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -35,7 +35,7 @@ class crm_lead2partner(osv.osv_memory):
|
|||
}
|
||||
def view_init(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function checks for precondition before wizard executes
|
||||
Check for precondition before wizard executes.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -69,22 +69,19 @@ class crm_lead2partner(osv.osv_memory):
|
|||
return partner_id
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
"""
|
||||
res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
|
||||
res = super(crm_lead2partner, self).default_get(cr, uid, fields, context=context)
|
||||
partner_id = self._select_partner(cr, uid, context=context)
|
||||
|
||||
if 'partner_id' in fields:
|
||||
res.update({'partner_id': partner_id})
|
||||
if 'action' in fields:
|
||||
res.update({'action': partner_id and 'exist' or 'create'})
|
||||
|
||||
|
||||
return res
|
||||
|
||||
def open_create_partner(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This function Opens form of create partner.
|
||||
Open form of create partner.
|
||||
"""
|
||||
view_obj = self.pool.get('ir.ui.view')
|
||||
view_id = view_obj.search(cr, uid, [('model', '=', self._name), \
|
||||
|
@ -101,21 +98,21 @@ class crm_lead2partner(osv.osv_memory):
|
|||
|
||||
def _create_partner(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This function Creates partner based on action.
|
||||
Create partner based on action.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
lead = self.pool.get('crm.lead')
|
||||
lead_ids = context and context.get('active_ids') or []
|
||||
lead_ids = context.get('active_ids', [])
|
||||
data = self.browse(cr, uid, ids, context=context)[0]
|
||||
partner_id = data.partner_id and data.partner_id.id or False
|
||||
return lead.convert_partner(cr, uid, lead_ids, data.action, partner_id, context=context)
|
||||
|
||||
def make_partner(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This function Makes partner based on action.
|
||||
Make a partner based on action.
|
||||
Only called from form view, so only meant to convert one lead at a time.
|
||||
"""
|
||||
# Only called from Form view, so only meant to convert one Lead.
|
||||
lead_id = context and context.get('active_id') or False
|
||||
partner_ids_map = self._create_partner(cr, uid, ids, context=context)
|
||||
return self.pool.get('res.partner').redirect_partner_form(cr, uid, partner_ids_map.get(lead_id, False), context=context)
|
||||
|
|
|
@ -244,6 +244,7 @@ class crm_segmentation(osv.osv):
|
|||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of crm segmentation’s IDs """
|
||||
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
categs = self.read(cr,uid,ids,['categ_id','exclusif','partner_id', \
|
||||
'sales_purchase_active', 'profiling_active'])
|
||||
for categ in categs:
|
||||
|
@ -280,8 +281,10 @@ class crm_segmentation(osv.osv):
|
|||
for pid in to_remove_list:
|
||||
partners.remove(pid)
|
||||
|
||||
for partner_id in partners:
|
||||
cr.execute('insert into res_partner_res_partner_category_rel (category_id,partner_id) values (%s,%s)', (categ['categ_id'][0],partner_id))
|
||||
for partner in partner_obj.browse(cr, uid, partners):
|
||||
category_ids = [categ_id.id for categ_id in partner.category_id]
|
||||
if categ['categ_id'][0] not in category_ids:
|
||||
cr.execute('insert into res_partner_res_partner_category_rel (category_id,partner_id) values (%s,%s)', (categ['categ_id'][0],partner.id))
|
||||
|
||||
self.write(cr, uid, [id], {'state':'not running', 'partner_id':0})
|
||||
return True
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# Spanish translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-11-06 15:26+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-07 04:38+0000\n"
|
||||
"X-Generator: Launchpad (build 16232)\n"
|
||||
|
||||
#. module: crm_todo
|
||||
#: model:ir.model,name:crm_todo.model_project_task
|
||||
msgid "Task"
|
||||
msgstr "Tarea"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Timebox"
|
||||
msgstr "Periodo de tiempo"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "For cancelling the task"
|
||||
msgstr "Para cancelar la tarea"
|
||||
|
||||
#. module: crm_todo
|
||||
#: constraint:project.task:0
|
||||
msgid "Error ! Task end-date must be greater then task start-date"
|
||||
msgstr ""
|
||||
"¡ Error ! La fecha final de la tarea debe ser mayor que la fecha de inicio"
|
||||
|
||||
#. module: crm_todo
|
||||
#: model:ir.model,name:crm_todo.model_crm_lead
|
||||
msgid "crm.lead"
|
||||
msgstr "crm.iniciativa"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Next"
|
||||
msgstr "Siguiente"
|
||||
|
||||
#. module: crm_todo
|
||||
#: model:ir.actions.act_window,name:crm_todo.crm_todo_action
|
||||
#: model:ir.ui.menu,name:crm_todo.menu_crm_todo
|
||||
msgid "My Tasks"
|
||||
msgstr "Mis tareas"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
#: field:crm.lead,task_ids:0
|
||||
msgid "Tasks"
|
||||
msgstr "Tareas"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Done"
|
||||
msgstr "Realizado"
|
||||
|
||||
#. module: crm_todo
|
||||
#: constraint:project.task:0
|
||||
msgid "Error ! You cannot create recursive tasks."
|
||||
msgstr "¡Error! No se pueden crear tareas recursivas."
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Extra Info"
|
||||
msgstr "Información extra"
|
||||
|
||||
#. module: crm_todo
|
||||
#: field:project.task,lead_id:0
|
||||
msgid "Lead / Opportunity"
|
||||
msgstr "Iniciativa / Oportunidad"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "For changing to done state"
|
||||
msgstr "Para cambiar a estado 'Realizada'"
|
||||
|
||||
#. module: crm_todo
|
||||
#: view:crm.lead:0
|
||||
msgid "Previous"
|
||||
msgstr "Anterior"
|
|
@ -322,7 +322,6 @@
|
|||
|
||||
<record id="view_picking_withcarrier_in_form" model="ir.ui.view">
|
||||
<field name="name">delivery.stock.picking_withcarrier.in.form.view</field>
|
||||
<field name="type">form</field>
|
||||
<field name="model">stock.picking.in</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||
<field name="arch" type="xml">
|
||||
|
|
|
@ -15,7 +15,7 @@ openerp.edi.EdiView = openerp.web.Widget.extend({
|
|||
this._super();
|
||||
var self = this;
|
||||
var param = {"db": self.db, "token": self.token};
|
||||
return self.rpc('/edi/get_edi_document', param).then(this.on_document_loaded, this.on_document_failed);
|
||||
return self.rpc('/edi/get_edi_document', param).done(this.on_document_loaded).fail(this.on_document_failed);
|
||||
},
|
||||
on_document_loaded: function(docs){
|
||||
this.doc = docs[0];
|
||||
|
@ -108,7 +108,7 @@ openerp.edi.EdiView = openerp.web.Widget.extend({
|
|||
});
|
||||
|
||||
openerp.edi.edi_view = function (db, token) {
|
||||
openerp.session.session_bind().then(function () {
|
||||
openerp.session.session_bind().done(function () {
|
||||
new openerp.edi.EdiView(null,db,token).appendTo($("body").addClass('openerp'));
|
||||
});
|
||||
}
|
||||
|
@ -149,11 +149,11 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
|
|||
},
|
||||
|
||||
do_import: function() {
|
||||
this.rpc('/edi/import_edi_url', {url: this.url}).then(this.on_imported, this.on_imported_error);
|
||||
this.rpc('/edi/import_edi_url', {url: this.url}).done(this.on_imported).fail(this.on_imported_error);
|
||||
},
|
||||
on_imported: function(response) {
|
||||
if ('action' in response) {
|
||||
this.rpc("/web/session/save_session_action", {the_action: response.action}).then(function(key) {
|
||||
this.rpc("/web/session/save_session_action", {the_action: response.action}).done(function(key) {
|
||||
window.location = "/#sa="+encodeURIComponent(key);
|
||||
});
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ openerp.edi.EdiImport = openerp.web.Widget.extend({
|
|||
});
|
||||
|
||||
openerp.edi.edi_import = function (url) {
|
||||
openerp.session.session_bind().then(function () {
|
||||
openerp.session.session_bind().done(function () {
|
||||
new openerp.edi.EdiImport(null,url).appendTo($("body").addClass('openerp'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -510,7 +510,7 @@
|
|||
<field name="model">event.registration</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Event Registration">
|
||||
<field name="name" string="Participant" filter_domain="['|','|','|',('name','ilike',self),('partner_id','ilike',self),('email','ilike',self),('origin','ilike',self)]"/>
|
||||
<field name="name" string="Participant" filter_domain="['|','|',('name','ilike',self),('email','ilike',self),('origin','ilike',self)]"/>
|
||||
<filter icon="terp-mail-message-new" string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/>
|
||||
<separator/>
|
||||
<filter icon="terp-check" string="New" name="draft" domain="[('state','=','draft')]" help="Registrations in unconfirmed state"/>
|
||||
|
@ -519,6 +519,7 @@
|
|||
<filter icon="terp-personal" string="My Registrations" help="My Registrations" domain="[('user_id','=',uid)]"/>
|
||||
<field name="event_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="partner_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Responsible" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Partner" icon="terp-partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
import fleet
|
|
@ -0,0 +1,61 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
'name' : 'Fleet Management',
|
||||
'version' : '0.1',
|
||||
'author' : 'OpenERP S.A.',
|
||||
'category': 'Managing vehicles and contracts',
|
||||
'website' : 'http://www.openerp.com',
|
||||
'summary' : 'Vehicle, leasing, insurances, costs',
|
||||
'description' : """
|
||||
Vehicle, leasing, insurances, cost
|
||||
==================================
|
||||
With this module, OpenERP helps you managing all your vehicles, the
|
||||
contracts associated to those vehicle as well as services, fuel log
|
||||
entries, costs and many other features necessary to the management
|
||||
of your fleet of vehicle(s)
|
||||
|
||||
Main Features
|
||||
-------------
|
||||
* Add vehicles to your fleet
|
||||
* Manage contracts for vehicles
|
||||
* Reminder when a contract reach its expiration date
|
||||
* Add services, fuel log entry, odometer values for all vehicles
|
||||
* Show all costs associated to a vehicle or to a type of service
|
||||
* Analysis graph for costs
|
||||
""",
|
||||
'depends' : [
|
||||
'base',
|
||||
'mail',
|
||||
'board'
|
||||
],
|
||||
'data' : [
|
||||
'fleet_view.xml',
|
||||
'fleet_data.xml',
|
||||
'fleet_board_view.xml',
|
||||
],
|
||||
'update_xml' : ['security/ir.model.access.csv'],
|
||||
|
||||
'demo': ['fleet_cars.xml','fleet_demo.xml'],
|
||||
|
||||
'installable' : True,
|
||||
'application' : True,
|
||||
}
|
|
@ -0,0 +1,818 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import time
|
||||
import datetime
|
||||
import tools
|
||||
from osv.orm import except_orm
|
||||
from tools.translate import _
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
def str_to_datetime(strdate):
|
||||
return datetime.datetime.strptime(strdate, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
class fleet_vehicle_cost(osv.Model):
|
||||
_name = 'fleet.vehicle.cost'
|
||||
_description = 'Cost related to a vehicle'
|
||||
_order = 'date desc, vehicle_id asc'
|
||||
|
||||
def _get_odometer(self, cr, uid, ids, odometer_id, arg, context):
|
||||
res = dict.fromkeys(ids, False)
|
||||
for record in self.browse(cr,uid,ids,context=context):
|
||||
if record.odometer_id:
|
||||
res[record.id] = record.odometer_id.value
|
||||
return res
|
||||
|
||||
def _set_odometer(self, cr, uid, id, name, value, args=None, context=None):
|
||||
if not value:
|
||||
raise except_orm(_('Operation not allowed!'), _('Emptying the odometer value of a vehicle is not allowed.'))
|
||||
date = self.browse(cr, uid, id, context=context).date
|
||||
if not(date):
|
||||
date = fields.date.context_today(self, cr, uid, context=context)
|
||||
vehicle_id = self.browse(cr, uid, id, context=context).vehicle_id
|
||||
data = {'value': value, 'date': date, 'vehicle_id': vehicle_id.id}
|
||||
odometer_id = self.pool.get('fleet.vehicle.odometer').create(cr, uid, data, context=context)
|
||||
return self.write(cr, uid, id, {'odometer_id': odometer_id}, context=context)
|
||||
|
||||
def _year_get_fnc(self, cr, uid, ids, name, unknow_none, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
res[record.id] = str(time.strptime(record.date, tools.DEFAULT_SERVER_DATE_FORMAT).tm_year)
|
||||
return res
|
||||
|
||||
def _cost_name_get_fnc(self, cr, uid, ids, name, unknow_none, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
name = record.vehicle_id.name
|
||||
if record.cost_subtype.name:
|
||||
name += ' / '+ record.cost_subtype.name
|
||||
if record.date:
|
||||
name += ' / '+ record.date
|
||||
res[record.id] = name
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.function(_cost_name_get_fnc, type="char", string='Name', store=True),
|
||||
'vehicle_id': fields.many2one('fleet.vehicle', 'Vehicle', required=True, help='Vehicle concerned by this log'),
|
||||
'cost_subtype': fields.many2one('fleet.service.type', 'Type', help='Cost type purchased with this cost'),
|
||||
'amount': fields.float('Total Price'),
|
||||
'cost_type': fields.selection([('contract', 'Contract'), ('services','Services'), ('fuel','Fuel'), ('other','Other')], 'Category of the cost', help='For internal purpose only', required=True),
|
||||
'parent_id': fields.many2one('fleet.vehicle.cost', 'Parent', help='Parent cost to this current cost'),
|
||||
'cost_ids': fields.one2many('fleet.vehicle.cost', 'parent_id', 'Included Services'),
|
||||
'odometer_id': fields.many2one('fleet.vehicle.odometer', 'Odometer', help='Odometer measure of the vehicle at the moment of this log'),
|
||||
'odometer': fields.function(_get_odometer, fnct_inv=_set_odometer, type='float', string='Odometer Value', help='Odometer measure of the vehicle at the moment of this log'),
|
||||
'odometer_unit': fields.related('vehicle_id', 'odometer_unit', type="char", string="Unit", readonly=True),
|
||||
'date' :fields.date('Date',help='Date when the cost has been executed'),
|
||||
'contract_id': fields.many2one('fleet.vehicle.log.contract', 'Contract', help='Contract attached to this cost'),
|
||||
'auto_generated': fields.boolean('Automatically Generated', readonly=True, required=True),
|
||||
'year': fields.function(_year_get_fnc, type="char", string='Year', store=True),
|
||||
}
|
||||
|
||||
_defaults ={
|
||||
'cost_type': 'other',
|
||||
}
|
||||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
#make sure that the data are consistent with values of parent and contract records given
|
||||
if 'parent_id' in data and data['parent_id']:
|
||||
parent = self.browse(cr, uid, data['parent_id'], context=context)
|
||||
data['vehicle_id'] = parent.vehicle_id.id
|
||||
data['date'] = parent.date
|
||||
data['cost_type'] = parent.cost_type
|
||||
if 'contract_id' in data and data['contract_id']:
|
||||
contract = self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, data['contract_id'], context=context)
|
||||
data['vehicle_id'] = contract.vehicle_id.id
|
||||
data['cost_subtype'] = contract.cost_subtype.id
|
||||
data['cost_type'] = contract.cost_type
|
||||
if 'odometer' in data and not data['odometer']:
|
||||
#if received value for odometer is 0, then remove it from the data as it would result to the creation of a
|
||||
#odometer log with 0, which is to be avoided
|
||||
del(data['odometer'])
|
||||
return super(fleet_vehicle_cost, self).create(cr, uid, data, context=context)
|
||||
|
||||
|
||||
class fleet_vehicle_tag(osv.Model):
|
||||
_name = 'fleet.vehicle.tag'
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True, translate=True),
|
||||
}
|
||||
|
||||
class fleet_vehicle_state(osv.Model):
|
||||
_name = 'fleet.vehicle.state'
|
||||
_order = 'sequence asc'
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'sequence': fields.integer('Order', help="Used to order the note stages")
|
||||
}
|
||||
_sql_constraints = [('fleet_state_name_unique','unique(name)', 'State name already exists')]
|
||||
|
||||
|
||||
class fleet_vehicle_model(osv.Model):
|
||||
|
||||
def _model_name_get_fnc(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
name = record.modelname
|
||||
if record.brand.name:
|
||||
name = record.brand.name + ' / ' + name
|
||||
res[record.id] = name
|
||||
return res
|
||||
|
||||
def on_change_brand(self, cr, uid, ids, model_id, context=None):
|
||||
if not model_id:
|
||||
return {'value': {'image_medium': False}}
|
||||
brand = self.pool.get('fleet.vehicle.model.brand').browse(cr, uid, model_id, context=context)
|
||||
return {
|
||||
'value': {
|
||||
'image_medium': brand.image,
|
||||
}
|
||||
}
|
||||
|
||||
_name = 'fleet.vehicle.model'
|
||||
_description = 'Model of a vehicle'
|
||||
_order = 'name asc'
|
||||
|
||||
_columns = {
|
||||
'name': fields.function(_model_name_get_fnc, type="char", string='Name', store=True),
|
||||
'modelname': fields.char('Model name', size=32, required=True),
|
||||
'brand': fields.many2one('fleet.vehicle.model.brand', 'Model Brand', required=True, help='Brand of the vehicle'),
|
||||
'vendors': fields.many2many('res.partner', 'fleet_vehicle_model_vendors', 'model_id', 'partner_id', string='Vendors'),
|
||||
'image': fields.related('brand', 'image', type="binary", string="Logo"),
|
||||
'image_medium': fields.related('brand', 'image_medium', type="binary", string="Logo"),
|
||||
'image_small': fields.related('brand', 'image_small', type="binary", string="Logo"),
|
||||
}
|
||||
|
||||
|
||||
class fleet_vehicle_model_brand(osv.Model):
|
||||
_name = 'fleet.vehicle.model.brand'
|
||||
_description = 'Brand model of the vehicle'
|
||||
|
||||
_order = 'name asc'
|
||||
|
||||
def _get_image(self, cr, uid, ids, name, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
result[obj.id] = tools.image_get_resized_images(obj.image)
|
||||
return result
|
||||
|
||||
def _set_image(self, cr, uid, id, name, value, args, context=None):
|
||||
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Brand Name', size=64, required=True),
|
||||
'image': fields.binary("Logo",
|
||||
help="This field holds the image used as logo for the brand, limited to 1024x1024px."),
|
||||
'image_medium': fields.function(_get_image, fnct_inv=_set_image,
|
||||
string="Medium-sized photo", type="binary", multi="_get_image",
|
||||
store = {
|
||||
'fleet.vehicle.model.brand': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
|
||||
},
|
||||
help="Medium-sized logo of the brand. It is automatically "\
|
||||
"resized as a 128x128px image, with aspect ratio preserved. "\
|
||||
"Use this field in form views or some kanban views."),
|
||||
'image_small': fields.function(_get_image, fnct_inv=_set_image,
|
||||
string="Smal-sized photo", type="binary", multi="_get_image",
|
||||
store = {
|
||||
'fleet.vehicle.model.brand': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10),
|
||||
},
|
||||
help="Small-sized photo of the brand. It is automatically "\
|
||||
"resized as a 64x64px image, with aspect ratio preserved. "\
|
||||
"Use this field anywhere a small image is required."),
|
||||
}
|
||||
|
||||
|
||||
class fleet_vehicle(osv.Model):
|
||||
|
||||
_inherit = 'mail.thread'
|
||||
|
||||
def _vehicle_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
res[record.id] = record.model_id.brand.name + '/' + record.model_id.modelname + ' / ' + record.license_plate
|
||||
return res
|
||||
|
||||
def return_action_to_open(self, cr, uid, ids, context=None):
|
||||
""" This opens the xml view specified in xml_id for the current vehicle """
|
||||
if context is None:
|
||||
context = {}
|
||||
if context.get('xml_id'):
|
||||
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet', context['xml_id'], context=context)
|
||||
res['context'] = context
|
||||
res['context'].update({'default_vehicle_id': ids[0]})
|
||||
res['domain'] = [('vehicle_id','=', ids[0])]
|
||||
return res
|
||||
return False
|
||||
|
||||
def act_show_log_cost(self, cr, uid, ids, context=None):
|
||||
""" This opens log view to view and add new log for this vehicle, groupby default to only show effective costs
|
||||
@return: the costs log view
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
res = self.pool.get('ir.actions.act_window').for_xml_id(cr, uid ,'fleet','fleet_vehicle_costs_act', context=context)
|
||||
res['context'] = context
|
||||
res['context'].update({
|
||||
'default_vehicle_id': ids[0],
|
||||
'search_default_parent_false': True
|
||||
})
|
||||
res['domain'] = [('vehicle_id','=', ids[0])]
|
||||
return res
|
||||
|
||||
def _get_odometer(self, cr, uid, ids, odometer_id, arg, context):
|
||||
res = dict.fromkeys(ids, 0)
|
||||
for record in self.browse(cr,uid,ids,context=context):
|
||||
ids = self.pool.get('fleet.vehicle.odometer').search(cr, uid, [('vehicle_id', '=', record.id)], limit=1, order='value desc')
|
||||
if len(ids) > 0:
|
||||
res[record.id] = self.pool.get('fleet.vehicle.odometer').browse(cr, uid, ids[0], context=context).value
|
||||
return res
|
||||
|
||||
def _set_odometer(self, cr, uid, id, name, value, args=None, context=None):
|
||||
if value:
|
||||
date = fields.date.context_today(self, cr, uid, context=context)
|
||||
data = {'value': value, 'date': date, 'vehicle_id': id}
|
||||
return self.pool.get('fleet.vehicle.odometer').create(cr, uid, data, context=context)
|
||||
|
||||
def _search_get_overdue_contract_reminder(self, cr, uid, obj, name, args, context):
|
||||
res = []
|
||||
today = fields.date.today(self, cr, uid, context=context)
|
||||
for field, operator, value in args:
|
||||
assert operator in ('=', '!=', '<>') and value in (True, False), 'Operation not supported'
|
||||
if (operator == '=' and value == True) or (operator in ('<>', '!=') and value == False):
|
||||
search_operator = 'in'
|
||||
else:
|
||||
search_operator = 'not in'
|
||||
today = fields.date.context_today(self, cr, uid, context=context)
|
||||
cr.execute('select cost.vehicle_id, count(contract.id) as contract_number FROM fleet_vehicle_cost cost left join fleet_vehicle_log_contract contract on contract.cost_id = cost.id WHERE contract.expiration_date is not null AND contract.expiration_date < %s AND contract.state IN (\'open\', \'toclose\') GROUP BY cost.vehicle_id', (today,))
|
||||
res_ids = [x[0] for x in cr.fetchall()]
|
||||
res.append(('id', search_operator, res_ids))
|
||||
return res
|
||||
|
||||
def _search_contract_renewal_due_soon(self, cr, uid, obj, name, args, context):
|
||||
res = []
|
||||
for field, operator, value in args:
|
||||
assert operator in ('=', '!=', '<>') and value in (True, False), 'Operation not supported'
|
||||
if (operator == '=' and value == True) or (operator in ('<>', '!=') and value == False):
|
||||
search_operator = 'in'
|
||||
else:
|
||||
search_operator = 'not in'
|
||||
today = fields.date.context_today(self, cr, uid, context=context)
|
||||
datetime_today = datetime.datetime.strptime(today, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
limit_date = str((datetime_today + relativedelta(days=+15)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT))
|
||||
cr.execute('select cost.vehicle_id, count(contract.id) as contract_number FROM fleet_vehicle_cost cost left join fleet_vehicle_log_contract contract on contract.cost_id = cost.id WHERE contract.expiration_date is not null AND contract.expiration_date > %s AND contract.expiration_date < %s AND contract.state IN (\'open\', \'toclose\') GROUP BY cost.vehicle_id', (today, limit_date))
|
||||
res_ids = [x[0] for x in cr.fetchall()]
|
||||
res.append(('id', search_operator, res_ids))
|
||||
return res
|
||||
|
||||
def _get_contract_reminder_fnc(self, cr, uid, ids, field_names, unknow_none, context=None):
|
||||
res= {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
overdue = False
|
||||
due_soon = False
|
||||
total = 0
|
||||
name = ''
|
||||
for element in record.log_contracts:
|
||||
if element.state in ('open', 'toclose') and element.expiration_date:
|
||||
current_date_str = fields.date.context_today(self, cr, uid, context=context)
|
||||
due_time_str = element.expiration_date
|
||||
current_date = str_to_datetime(current_date_str)
|
||||
due_time = str_to_datetime(due_time_str)
|
||||
diff_time = (due_time-current_date).days
|
||||
if diff_time < 0:
|
||||
overdue = True
|
||||
total += 1
|
||||
if diff_time < 15 and diff_time >= 0:
|
||||
due_soon = True;
|
||||
total += 1
|
||||
if overdue or due_soon:
|
||||
ids = self.pool.get('fleet.vehicle.log.contract').search(cr,uid,[('vehicle_id', '=', record.id), ('state', 'in', ('open', 'toclose'))], limit=1, order='expiration_date asc')
|
||||
if len(ids) > 0:
|
||||
#we display only the name of the oldest overdue/due soon contract
|
||||
name=(self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, ids[0], context=context).cost_subtype.name)
|
||||
|
||||
res[record.id] = {
|
||||
'contract_renewal_overdue': overdue,
|
||||
'contract_renewal_due_soon': due_soon,
|
||||
'contract_renewal_total': (total - 1), #we remove 1 from the real total for display purposes
|
||||
'contract_renewal_name': name,
|
||||
}
|
||||
return res
|
||||
|
||||
def _get_default_state(self, cr, uid, context):
|
||||
try:
|
||||
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'vehicle_state_active')
|
||||
except ValueError:
|
||||
model_id = False
|
||||
return model_id
|
||||
|
||||
_name = 'fleet.vehicle'
|
||||
_description = 'Information on a vehicle'
|
||||
_order= 'license_plate asc'
|
||||
_columns = {
|
||||
'name': fields.function(_vehicle_name_get_fnc, type="char", string='Name', store=True),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'license_plate': fields.char('License Plate', size=32, required=True, help='License plate number of the vehicle (ie: plate number for a car)'),
|
||||
'vin_sn': fields.char('Chassis Number', size=32, help='Unique number written on the vehicle motor (VIN/SN number)'),
|
||||
'driver': fields.many2one('res.partner', 'Driver', help='Driver of the vehicle'),
|
||||
'model_id': fields.many2one('fleet.vehicle.model', 'Model', required=True, help='Model of the vehicle'),
|
||||
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
|
||||
'log_services': fields.one2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs'),
|
||||
'log_contracts': fields.one2many('fleet.vehicle.log.contract', 'vehicle_id', 'Contracts'),
|
||||
'acquisition_date': fields.date('Acquisition Date', required=False, help='Date when the vehicle has been bought'),
|
||||
'color': fields.char('Color', size=32, help='Color of the vehicle'),
|
||||
'state': fields.many2one('fleet.vehicle.state', 'State', help='Current state of the vehicle', ondelete="set null"),
|
||||
'location': fields.char('Location', size=128, help='Location of the vehicle (garage, ...)'),
|
||||
'seats': fields.integer('Seats Number', help='Number of seats of the vehicle'),
|
||||
'doors': fields.integer('Doors Number', help='Number of doors of the vehicle'),
|
||||
'tag_ids' :fields.many2many('fleet.vehicle.tag', 'fleet_vehicle_vehicle_tag_rel', 'vehicle_tag_id','tag_id', 'Tags'),
|
||||
'odometer': fields.function(_get_odometer, fnct_inv=_set_odometer, type='float', string='Odometer Value', help='Odometer measure of the vehicle at the moment of this log'),
|
||||
'odometer_unit': fields.selection([('kilometers', 'Kilometers'),('miles','Miles')], 'Odometer Unit', help='Unit of the odometer ',required=True),
|
||||
'transmission': fields.selection([('manual', 'Manual'), ('automatic', 'Automatic')], 'Transmission', help='Transmission Used by the vehicle'),
|
||||
'fuel_type': fields.selection([('gasoline', 'Gasoline'), ('diesel', 'Diesel'), ('electric', 'Electric'), ('hybrid', 'Hybrid')], 'Fuel Type', help='Fuel Used by the vehicle'),
|
||||
'horsepower': fields.integer('Horsepower'),
|
||||
'horsepower_tax': fields.float('Horsepower Taxation'),
|
||||
'power': fields.integer('Power (kW)', help='Power in kW of the vehicle'),
|
||||
'co2': fields.float('CO2 Emissions', help='CO2 emissions of the vehicle'),
|
||||
'image': fields.related('model_id', 'image', type="binary", string="Logo"),
|
||||
'image_medium': fields.related('model_id', 'image_medium', type="binary", string="Logo"),
|
||||
'image_small': fields.related('model_id', 'image_small', type="binary", string="Logo"),
|
||||
'contract_renewal_due_soon': fields.function(_get_contract_reminder_fnc, fnct_search=_search_contract_renewal_due_soon, type="boolean", string='Has Contracts to renew', multi='contract_info'),
|
||||
'contract_renewal_overdue': fields.function(_get_contract_reminder_fnc, fnct_search=_search_get_overdue_contract_reminder, type="boolean", string='Has Contracts Overdued', multi='contract_info'),
|
||||
'contract_renewal_name': fields.function(_get_contract_reminder_fnc, type="text", string='Name of contract to renew soon', multi='contract_info'),
|
||||
'contract_renewal_total': fields.function(_get_contract_reminder_fnc, type="integer", string='Total of contracts due or overdue minus one', multi='contract_info'),
|
||||
'car_value': fields.float('Car Value', help='Value of the bought vehicle'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'doors': 5,
|
||||
'odometer_unit': 'kilometers',
|
||||
'state': _get_default_state,
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if not default:
|
||||
default = {}
|
||||
default.update({
|
||||
'log_fuel':[],
|
||||
'log_contracts':[],
|
||||
'log_services':[],
|
||||
'tag_ids':[],
|
||||
'vin_sn':'',
|
||||
})
|
||||
return super(fleet_vehicle, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def on_change_model(self, cr, uid, ids, model_id, context=None):
|
||||
if not model_id:
|
||||
return {}
|
||||
model = self.pool.get('fleet.vehicle.model').browse(cr, uid, model_id, context=context)
|
||||
return {
|
||||
'value': {
|
||||
'image_medium': model.image,
|
||||
}
|
||||
}
|
||||
|
||||
def create(self, cr, uid, data, context=None):
|
||||
vehicle_id = super(fleet_vehicle, self).create(cr, uid, data, context=context)
|
||||
vehicle = self.browse(cr, uid, vehicle_id, context=context)
|
||||
self.message_post(cr, uid, [vehicle_id], body=_('Vehicle %s has been added to the fleet!') % (vehicle.license_plate), context=context)
|
||||
return vehicle_id
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""
|
||||
This function write an entry in the openchatter whenever we change important information
|
||||
on the vehicle like the model, the drive, the state of the vehicle or its license plate
|
||||
"""
|
||||
for vehicle in self.browse(cr, uid, ids, context):
|
||||
changes = []
|
||||
if 'model_id' in vals and vehicle.model_id.id != vals['model_id']:
|
||||
value = self.pool.get('fleet.vehicle.model').browse(cr,uid,vals['model_id'],context=context).name
|
||||
oldmodel = vehicle.model_id.name or _('None')
|
||||
changes.append(_("Model: from '%s' to '%s'") %(oldmodel, value))
|
||||
if 'driver' in vals and vehicle.driver.id != vals['driver']:
|
||||
value = self.pool.get('res.partner').browse(cr,uid,vals['driver'],context=context).name
|
||||
olddriver = (vehicle.driver.name) or _('None')
|
||||
changes.append(_("Driver: from '%s' to '%s'") %(olddriver, value))
|
||||
if 'state' in vals and vehicle.state.id != vals['state']:
|
||||
value = self.pool.get('fleet.vehicle.state').browse(cr,uid,vals['state'],context=context).name
|
||||
oldstate = vehicle.state.name or _('None')
|
||||
changes.append(_("State: from '%s' to '%s'") %(oldstate, value))
|
||||
if 'license_plate' in vals and vehicle.license_plate != vals['license_plate']:
|
||||
old_license_plate = vehicle.license_plate or _('None')
|
||||
changes.append(_("License Plate: from '%s' to '%s'") %(old_license_plate, vals['license_plate']))
|
||||
|
||||
if len(changes) > 0:
|
||||
self.message_post(cr, uid, [vehicle.id], body=", ".join(changes), context=context)
|
||||
|
||||
vehicle_id = super(fleet_vehicle,self).write(cr, uid, ids, vals, context)
|
||||
return True
|
||||
|
||||
|
||||
class fleet_vehicle_odometer(osv.Model):
|
||||
_name='fleet.vehicle.odometer'
|
||||
_description='Odometer log for a vehicle'
|
||||
_order='date desc'
|
||||
|
||||
def _vehicle_log_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
name = record.vehicle_id.name
|
||||
if record.date:
|
||||
name = name+ ' / '+ str(record.date)
|
||||
res[record.id] = name
|
||||
return res
|
||||
|
||||
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
|
||||
if not vehicle_id:
|
||||
return {}
|
||||
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
|
||||
return {
|
||||
'value': {
|
||||
'unit': odometer_unit,
|
||||
}
|
||||
}
|
||||
|
||||
_columns = {
|
||||
'name': fields.function(_vehicle_log_name_get_fnc, type="char", string='Name', store=True),
|
||||
'date': fields.date('Date'),
|
||||
'value': fields.float('Odometer Value', group_operator="max"),
|
||||
'vehicle_id': fields.many2one('fleet.vehicle', 'Vehicle', required=True),
|
||||
'unit': fields.related('vehicle_id', 'odometer_unit', type="char", string="Unit", readonly=True),
|
||||
}
|
||||
_defaults = {
|
||||
'date': fields.date.context_today,
|
||||
}
|
||||
|
||||
|
||||
class fleet_vehicle_log_fuel(osv.Model):
|
||||
|
||||
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
|
||||
if not vehicle_id:
|
||||
return {}
|
||||
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
|
||||
return {
|
||||
'value': {
|
||||
'odometer_unit': odometer_unit,
|
||||
}
|
||||
}
|
||||
|
||||
def on_change_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
|
||||
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
|
||||
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
|
||||
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
|
||||
#of 3.0/2=1.5)
|
||||
liter = float(liter)
|
||||
price_per_liter = float(price_per_liter)
|
||||
amount = float(amount)
|
||||
if liter > 0 and price_per_liter > 0:
|
||||
return {'value' : {'amount' : liter * price_per_liter,}}
|
||||
elif liter > 0 and amount > 0:
|
||||
return {'value' : {'price_per_liter' : amount / liter,}}
|
||||
elif price_per_liter > 0 and amount > 0:
|
||||
return {'value' : {'liter' : amount / price_per_liter,}}
|
||||
else :
|
||||
return {}
|
||||
|
||||
def on_change_price_per_liter(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
|
||||
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
|
||||
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
|
||||
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
|
||||
#of 3.0/2=1.5)
|
||||
liter = float(liter)
|
||||
price_per_liter = float(price_per_liter)
|
||||
amount = float(amount)
|
||||
if price_per_liter > 0 and liter > 0:
|
||||
return {'value' : {'amount' : liter * price_per_liter,}}
|
||||
elif price_per_liter > 0 and amount > 0:
|
||||
return {'value' : {'liter' : amount / price_per_liter,}}
|
||||
elif liter > 0 and amount > 0:
|
||||
return {'value' : {'price_per_liter' : amount / liter,}}
|
||||
else :
|
||||
return {}
|
||||
|
||||
def on_change_amount(self, cr, uid, ids, liter, price_per_liter, amount, context=None):
|
||||
#need to cast in float because the value receveid from web client maybe an integer (Javascript and JSON do not
|
||||
#make any difference between 3.0 and 3). This cause a problem if you encode, for example, 2 liters at 1.5 per
|
||||
#liter => total is computed as 3.0, then trigger an onchange that recomputes price_per_liter as 3/2=1 (instead
|
||||
#of 3.0/2=1.5)
|
||||
liter = float(liter)
|
||||
price_per_liter = float(price_per_liter)
|
||||
amount = float(amount)
|
||||
if amount > 0 and liter > 0:
|
||||
return {'value': {'price_per_liter': amount / liter,}}
|
||||
elif amount > 0 and price_per_liter > 0:
|
||||
return {'value': {'liter': amount / price_per_liter,}}
|
||||
elif liter > 0 and price_per_liter > 0:
|
||||
return {'value': {'amount': liter * price_per_liter,}}
|
||||
return {}
|
||||
|
||||
def _get_default_service_type(self, cr, uid, context):
|
||||
try:
|
||||
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_service_refueling')
|
||||
except ValueError:
|
||||
model_id = False
|
||||
return model_id
|
||||
|
||||
_name = 'fleet.vehicle.log.fuel'
|
||||
_description = 'Fuel log for vehicles'
|
||||
_inherits = {'fleet.vehicle.cost': 'cost_id'}
|
||||
|
||||
_columns = {
|
||||
'liter': fields.float('Liter'),
|
||||
'price_per_liter': fields.float('Price Per Liter'),
|
||||
'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
|
||||
'inv_ref': fields.char('Invoice Reference', size=64),
|
||||
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
|
||||
'notes': fields.text('Notes'),
|
||||
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
|
||||
}
|
||||
_defaults = {
|
||||
'purchaser_id': lambda self, cr, uid, ctx: uid,
|
||||
'date': fields.date.context_today,
|
||||
'cost_subtype': _get_default_service_type,
|
||||
'cost_type': 'fuel',
|
||||
}
|
||||
|
||||
|
||||
class fleet_vehicle_log_services(osv.Model):
|
||||
|
||||
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
|
||||
if not vehicle_id:
|
||||
return {}
|
||||
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
|
||||
return {
|
||||
'value': {
|
||||
'odometer_unit': odometer_unit,
|
||||
}
|
||||
}
|
||||
|
||||
def _get_default_service_type(self, cr, uid, context):
|
||||
try:
|
||||
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_service_service_8')
|
||||
except ValueError:
|
||||
model_id = False
|
||||
return model_id
|
||||
|
||||
_inherits = {'fleet.vehicle.cost': 'cost_id'}
|
||||
_name = 'fleet.vehicle.log.services'
|
||||
_description = 'Services for vehicles'
|
||||
_columns = {
|
||||
'purchaser_id': fields.many2one('res.partner', 'Purchaser', domain="['|',('customer','=',True),('employee','=',True)]"),
|
||||
'inv_ref': fields.char('Invoice Reference', size=64),
|
||||
'vendor_id': fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
|
||||
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
|
||||
'notes': fields.text('Notes'),
|
||||
}
|
||||
_defaults = {
|
||||
'purchaser_id': lambda self, cr, uid, ctx: uid,
|
||||
'date': fields.date.context_today,
|
||||
'cost_subtype': _get_default_service_type,
|
||||
'cost_type': 'services'
|
||||
}
|
||||
|
||||
|
||||
class fleet_service_type(osv.Model):
|
||||
_name = 'fleet.service.type'
|
||||
_description = 'Type of services available on a vehicle'
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True, translate=True),
|
||||
'category': fields.selection([('contract', 'Contract'), ('service', 'Service'), ('both', 'Both')], 'Category', required=True, help='Choose wheter the service refer to contracts, vehicle services or both'),
|
||||
}
|
||||
|
||||
|
||||
class fleet_vehicle_log_contract(osv.Model):
|
||||
|
||||
def scheduler_manage_auto_costs(self, cr, uid, context=None):
|
||||
#This method is called by a cron task
|
||||
#It creates costs for contracts having the "recurring cost" field setted, depending on their frequency
|
||||
#For example, if a contract has a reccuring cost of 200 with a weekly frequency, this method creates a cost of 200 on the first day of each week, from the date of the last recurring costs in the database to today
|
||||
#If the contract has not yet any recurring costs in the database, the method generates the recurring costs from the start_date to today
|
||||
#The created costs are associated to a contract thanks to the many2one field contract_id
|
||||
#If the contract has no start_date, no cost will be created, even if the contract has recurring costs
|
||||
vehicle_cost_obj = self.pool.get('fleet.vehicle.cost')
|
||||
d = datetime.datetime.strptime(fields.date.context_today(self, cr, uid, context=context), tools.DEFAULT_SERVER_DATE_FORMAT).date()
|
||||
contract_ids = self.pool.get('fleet.vehicle.log.contract').search(cr, uid, [('state','!=','closed')], offset=0, limit=None, order=None,context=None, count=False)
|
||||
deltas = {'yearly': relativedelta(years=+1), 'monthly': relativedelta(months=+1), 'weekly': relativedelta(weeks=+1), 'daily': relativedelta(days=+1)}
|
||||
for contract in self.pool.get('fleet.vehicle.log.contract').browse(cr, uid, contract_ids, context=context):
|
||||
if not contract.start_date or contract.cost_frequency == 'no':
|
||||
continue
|
||||
found = False
|
||||
last_cost_date = contract.start_date
|
||||
if contract.generated_cost_ids:
|
||||
last_autogenerated_cost_id = vehicle_cost_obj.search(cr, uid, ['&', ('contract_id','=',contract.id), ('auto_generated','=',True)], offset=0, limit=1, order='date desc',context=context, count=False)
|
||||
if last_autogenerated_cost_id:
|
||||
found = True
|
||||
last_cost_date = vehicle_cost_obj.browse(cr, uid, last_autogenerated_cost_id[0], context=context).date
|
||||
startdate = datetime.datetime.strptime(last_cost_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()
|
||||
if found:
|
||||
startdate += deltas.get(contract.cost_frequency)
|
||||
while (startdate < d) & (startdate < datetime.datetime.strptime(contract.expiration_date, tools.DEFAULT_SERVER_DATE_FORMAT).date()):
|
||||
data = {
|
||||
'amount': contract.cost_generated,
|
||||
'date': startdate.strftime(tools.DEFAULT_SERVER_DATE_FORMAT),
|
||||
'vehicle_id': contract.vehicle_id.id,
|
||||
'cost_subtype': contract.cost_subtype.id,
|
||||
'contract_id': contract.id,
|
||||
'auto_generated': True
|
||||
}
|
||||
cost_id = self.pool.get('fleet.vehicle.cost').create(cr, uid, data, context=context)
|
||||
startdate += deltas.get(contract.cost_frequency)
|
||||
return True
|
||||
|
||||
def scheduler_manage_contract_expiration(self, cr, uid, context=None):
|
||||
#This method is called by a cron task
|
||||
#It manages the state of a contract, possibly by posting a message on the vehicle concerned and updating its status
|
||||
datetime_today = datetime.datetime.strptime(fields.date.context_today(self, cr, uid, context=context), tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
limit_date = (datetime_today + relativedelta(days=+15)).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
ids = self.search(cr, uid, ['&', ('state', '=', 'open'), ('expiration_date', '<', limit_date)], offset=0, limit=None, order=None, context=context, count=False)
|
||||
res = {}
|
||||
for contract in self.browse(cr, uid, ids, context=context):
|
||||
if contract.vehicle_id.id in res:
|
||||
res[contract.vehicle_id.id] += 1
|
||||
else:
|
||||
res[contract.vehicle_id.id] = 1
|
||||
|
||||
for vehicle, value in res.items():
|
||||
self.pool.get('fleet.vehicle').message_post(cr, uid, vehicle, body=_('%s contract(s) need(s) to be renewed and/or closed!') % (str(value)), context=context)
|
||||
return self.write(cr, uid, ids, {'state': 'toclose'}, context=context)
|
||||
|
||||
def run_scheduler(self, cr, uid, context=None):
|
||||
self.scheduler_manage_auto_costs(cr, uid, context=context)
|
||||
self.scheduler_manage_contract_expiration(cr, uid, context=context)
|
||||
return True
|
||||
|
||||
def _vehicle_contract_name_get_fnc(self, cr, uid, ids, prop, unknow_none, context=None):
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
name = record.vehicle_id.name
|
||||
if record.cost_subtype.name:
|
||||
name += ' / '+ record.cost_subtype.name
|
||||
if record.date:
|
||||
name += ' / '+ record.date
|
||||
res[record.id] = name
|
||||
return res
|
||||
|
||||
def on_change_vehicle(self, cr, uid, ids, vehicle_id, context=None):
|
||||
if not vehicle_id:
|
||||
return {}
|
||||
odometer_unit = self.pool.get('fleet.vehicle').browse(cr, uid, vehicle_id, context=context).odometer_unit
|
||||
return {
|
||||
'value': {
|
||||
'odometer_unit': odometer_unit,
|
||||
}
|
||||
}
|
||||
|
||||
def compute_next_year_date(self, strdate):
|
||||
oneyear = datetime.timedelta(days=365)
|
||||
curdate = str_to_datetime(strdate)
|
||||
return datetime.datetime.strftime(curdate + oneyear, tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
def on_change_start_date(self, cr, uid, ids, strdate, enddate, context=None):
|
||||
if (strdate):
|
||||
return {'value': {'expiration_date': self.compute_next_year_date(strdate),}}
|
||||
return {}
|
||||
|
||||
def get_days_left(self, cr, uid, ids, prop, unknow_none, context=None):
|
||||
"""return a dict with as value for each contract an integer
|
||||
if contract is in an open state and is overdue, return 0
|
||||
if contract is in a closed state, return -1
|
||||
otherwise return the number of days before the contract expires
|
||||
"""
|
||||
res = {}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if (record.expiration_date and (record.state == 'open' or record.state == 'toclose')):
|
||||
today = str_to_datetime(time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT))
|
||||
renew_date = str_to_datetime(record.expiration_date)
|
||||
diff_time = (renew_date-today).days
|
||||
res[record.id] = diff_time > 0 and diff_time or 0
|
||||
else:
|
||||
res[record.id] = -1
|
||||
return res
|
||||
|
||||
def act_renew_contract(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1, "This operation should only be done for 1 single contract at a time, as it it suppose to open a window as result"
|
||||
for element in self.browse(cr, uid, ids, context=context):
|
||||
#compute end date
|
||||
startdate = str_to_datetime(element.start_date)
|
||||
enddate = str_to_datetime(element.expiration_date)
|
||||
diffdate = (enddate - startdate)
|
||||
default = {
|
||||
'date': fields.date.context_today(self, cr, uid, context=context),
|
||||
'start_date': datetime.datetime.strftime(str_to_datetime(element.expiration_date) + datetime.timedelta(days=1), tools.DEFAULT_SERVER_DATE_FORMAT),
|
||||
'expiration_date': datetime.datetime.strftime(enddate + diffdate, tools.DEFAULT_SERVER_DATE_FORMAT),
|
||||
}
|
||||
newid = super(fleet_vehicle_log_contract, self).copy(cr, uid, [element.id], default, context=context)
|
||||
mod, modid = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'fleet_vehicle_log_contract_form')
|
||||
return {
|
||||
'name':_("Renew Contract"),
|
||||
'view_mode': 'form',
|
||||
'view_id': modid,
|
||||
'view_type': 'tree,form',
|
||||
'res_model': 'fleet.vehicle.log.contract',
|
||||
'type': 'ir.actions.act_window',
|
||||
'nodestroy': True,
|
||||
'domain': '[]',
|
||||
'res_id': newid,
|
||||
'context': {'active_id':newid},
|
||||
}
|
||||
|
||||
def _get_default_contract_type(self, cr, uid, context=None):
|
||||
try:
|
||||
model, model_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'fleet', 'type_contract_leasing')
|
||||
except ValueError:
|
||||
model_id = False
|
||||
return model_id
|
||||
|
||||
def on_change_indic_cost(self, cr, uid, ids, cost_ids, context=None):
|
||||
totalsum = 0.0
|
||||
for element in cost_ids:
|
||||
if element and len(element) == 3 and element[2] is not False:
|
||||
totalsum += element[2].get('amount', 0.0)
|
||||
return {
|
||||
'value': {
|
||||
'sum_cost': totalsum,
|
||||
}
|
||||
}
|
||||
|
||||
def _get_sum_cost(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for contract in self.browse(cr, uid, ids, context=context):
|
||||
totalsum = 0
|
||||
for cost in contract.cost_ids:
|
||||
totalsum += cost.amount
|
||||
res[contract.id] = totalsum
|
||||
return res
|
||||
|
||||
_inherits = {'fleet.vehicle.cost': 'cost_id'}
|
||||
_name = 'fleet.vehicle.log.contract'
|
||||
_description = 'Contract information on a vehicle'
|
||||
_order='state desc,expiration_date'
|
||||
_columns = {
|
||||
'name': fields.function(_vehicle_contract_name_get_fnc, type="text", string='Name', store=True),
|
||||
'start_date': fields.date('Contract Start Date', help='Date when the coverage of the contract begins'),
|
||||
'expiration_date': fields.date('Contract Expiration Date', help='Date when the coverage of the contract expirates (by default, one year after begin date)'),
|
||||
'days_left': fields.function(get_days_left, type='integer', string='Warning Date'),
|
||||
'insurer_id' :fields.many2one('res.partner', 'Supplier', domain="[('supplier','=',True)]"),
|
||||
'purchaser_id': fields.many2one('res.partner', 'Contractor', domain="['|', ('customer','=',True), ('employee','=',True)]",help='Person to which the contract is signed for'),
|
||||
'ins_ref': fields.char('Contract Reference', size=64),
|
||||
'state': fields.selection([('open', 'In Progress'), ('toclose','To Close'), ('closed', 'Terminated')], 'Status', readonly=True, help='Choose wheter the contract is still valid or not'),
|
||||
'notes': fields.text('Terms and Conditions', help='Write here all supplementary informations relative to this contract'),
|
||||
'cost_generated': fields.float('Recurring Cost Amount', help="Costs paid at regular intervals, depending on the cost frequency. If the cost frequency is set to unique, the cost will be logged at the start date"),
|
||||
'cost_frequency': fields.selection([('no','No'), ('daily', 'Daily'), ('weekly','Weekly'), ('monthly','Monthly'), ('yearly','Yearly')], 'Recurring Cost Frequency', help='Frequency of the recuring cost', required=True),
|
||||
'generated_cost_ids': fields.one2many('fleet.vehicle.cost', 'contract_id', 'Generated Costs', ondelete='cascade'),
|
||||
'sum_cost': fields.function(_get_sum_cost, type='float', string='Indicative Costs Total'),
|
||||
'cost_amount': fields.related('cost_id', 'amount', string='Amount', type='float', store=True), #we need to keep this field as a related with store=True because the graph view doesn't support (1) to address fields from inherited table and (2) fields that aren't stored in database
|
||||
}
|
||||
_defaults = {
|
||||
'purchaser_id': lambda self, cr, uid, ctx: uid,
|
||||
'date': fields.date.context_today,
|
||||
'start_date': fields.date.context_today,
|
||||
'state':'open',
|
||||
'expiration_date': lambda self, cr, uid, ctx: self.compute_next_year_date(fields.date.context_today(self, cr, uid, context=ctx)),
|
||||
'cost_frequency': 'no',
|
||||
'cost_subtype': _get_default_contract_type,
|
||||
'cost_type': 'contract',
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
today = fields.date.context_today(self, cr, uid, context=context)
|
||||
default['date'] = today
|
||||
default['start_date'] = today
|
||||
default['expiration_date'] = self.compute_next_year_date(today)
|
||||
default['ins_ref'] = ''
|
||||
default['state'] = 'open'
|
||||
default['notes'] = ''
|
||||
return super(fleet_vehicle_log_contract, self).copy(cr, uid, id, default, context=context)
|
||||
|
||||
def contract_close(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state': 'closed'}, context=context)
|
||||
|
||||
def contract_open(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state': 'open'}, context=context)
|
||||
|
||||
class fleet_contract_state(osv.Model):
|
||||
_name = 'fleet.contract.state'
|
||||
_description = 'Contains the different possible status of a leasing contract'
|
||||
|
||||
_columns = {
|
||||
'name':fields.char('Contract Status', size=64, required=True),
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_fuel_graph">
|
||||
<field name="name">Fuel Costs by Month</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['&',('parent_id','=',False),('cost_type','=','fuel')]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_services_graph">
|
||||
<field name="name">Services Costs by Month</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_graph" />
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['&',('parent_id','=',False),('cost_type','=','services')]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_vehicle_log_contract_graph">
|
||||
<field name="name">Contracts Costs by Month</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['&',('parent_id','=',False),('cost_type','=','contract')]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_vehicle_costs_graph">
|
||||
<field name="name">Costs by Month</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_graph"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_vehicle_kanban">
|
||||
<field name="name">Vehicles with alerts</field>
|
||||
<field name="res_model">fleet.vehicle</field>
|
||||
<field name="view_id" ref="fleet_vehicle_kanban"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="domain">['|',('contract_renewal_due_soon','>',0),('contract_renewal_overdue','>',0)]</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here are displayed vehicles for which one or more contracts need to be renewed. If you see this message, then there is no contracts to renew.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_reporting_costs">
|
||||
<field name="name">Costs Analysis</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_tree"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{"search_default_parent_false" : True,"search_default_groupby_year" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_cost_subtype" : True, "search_default_groupby_vehicle_id" : True,}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
OpenERP helps you managing the costs for your different vehicles
|
||||
Costs are generally created from services and contract and appears here.
|
||||
</p>
|
||||
<p>
|
||||
Thanks to the different filters, OpenERP can only print the effective
|
||||
costs, sort them by type and by vehicle.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_fleet_reporting_costs_non_effective">
|
||||
<field name="name">Indicative Costs Analysis</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_id" ref="fleet_vehicle_costs_tree"></field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{"search_default_parent_true" : True,"search_default_groupby_cost_subtype" : True,"search_default_groupby_cost_type" : True,"search_default_groupby_parent_id" : True,}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
OpenERP helps you managing the costs for your different vehicles
|
||||
Costs are generally created from services and contract and appears here.
|
||||
</p>
|
||||
<p>
|
||||
Thanks to the different filters, OpenERP can only print the effective
|
||||
costs, sort them by type and by vehicle.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="board_fleet_form" model="ir.ui.view">
|
||||
<field name="name">board.fleet.form</field>
|
||||
<field name="model">board.board</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fleet Dashboard" version="7.0">
|
||||
<board style="2-1">
|
||||
<column>
|
||||
<action string="Vehicles With Alerts" name="%(fleet.action_fleet_vehicle_kanban)d" view_mode="kanban"/>
|
||||
<action string="Costs by Month" name="%(fleet.action_fleet_vehicle_costs_graph)d" view_mode="graph,tree"/>
|
||||
</column>
|
||||
<column>
|
||||
<action string="Fuel Costs" name="%(fleet.action_fleet_vehicle_log_fuel_graph)d" view_mode="graph,tree"/>
|
||||
<action string="Services Costs" name="%(fleet.action_fleet_vehicle_log_services_graph)d" view_mode="graph,tree"/>
|
||||
<action string="Contracts Costs" name="%(fleet.action_fleet_vehicle_log_contract_graph)d" view_mode="graph,tree"/>
|
||||
</column>
|
||||
</board>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="open_board_fleet" model="ir.actions.act_window">
|
||||
<field name="name">Fleet</field>
|
||||
<field name="res_model">board.board</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="usage">menu</field>
|
||||
<field name="view_id" ref="board_fleet_form"/>
|
||||
<field name="help" type="html">
|
||||
<div class="oe_empty_custom_dashboard">
|
||||
<p>
|
||||
<b>Fleet dashboard is empty.</b>
|
||||
</p><p>
|
||||
To add your first report into this dashboard, go to any
|
||||
menu, switch to list or graph view, and click <i>'Add to
|
||||
Dashboard'</i> in the extended search options.
|
||||
</p><p>
|
||||
You can filter and group data before inserting into the
|
||||
dashboard using the search options.
|
||||
</p>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_fleet_dashboard"
|
||||
parent="base.menu_reporting_dashboard"
|
||||
action="open_board_fleet"
|
||||
sequence="50"/>
|
||||
|
||||
<menuitem name="Fleet" parent="base.menu_reporting" id="menu_fleet_reporting" sequence="50" />
|
||||
|
||||
<menuitem id="menu_fleet_reporting_costs"
|
||||
parent="menu_fleet_reporting"
|
||||
action="action_fleet_reporting_costs"
|
||||
sequence="1"/>
|
||||
<menuitem id="menu_fleet_reporting_indicative_costs"
|
||||
parent="menu_fleet_reporting"
|
||||
action="action_fleet_reporting_costs_non_effective"
|
||||
sequence="2"/>
|
||||
</data>
|
||||
</openerp>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,440 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="0">
|
||||
<!--
|
||||
<record forcecreate="True" id="ir_cron_service_services_reminders" model="ir.cron">
|
||||
<field name="name">Creation of Vehicle services and Services renewals reminders</field>
|
||||
<field eval="True" name="active" />
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
<field eval="'fleet.vehicle'" name="model" />
|
||||
<field eval="'run_scheduler'" name="function" />
|
||||
<field eval="'()'" name="args" />
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record forcecreate="True" id="ir_cron_contract_costs_generator" model="ir.cron">
|
||||
<field name="name">Generation of contracts costs based on the costs frequency</field>
|
||||
<field eval="True" name="active" />
|
||||
<field name="user_id" ref="base.user_root" />
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">days</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall" />
|
||||
<field eval="'fleet.vehicle.log.contract'" name="model" />
|
||||
<field eval="'run_scheduler'" name="function" />
|
||||
<field eval="'()'" name="args" />
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_1" model="fleet.service.type">
|
||||
<field name="name">Calculation Benefit In Kind</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_2" model="fleet.service.type">
|
||||
<field name="name">Depreciation and Interests</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_3" model="fleet.service.type">
|
||||
<field name="name">Tax roll</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_5" model="fleet.service.type">
|
||||
<field name="name">Summer tires</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_6" model="fleet.service.type">
|
||||
<field name="name">Snow tires</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_7" model="fleet.service.type">
|
||||
<field name="name">Summer tires</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_8" model="fleet.service.type">
|
||||
<field name="name">Repair and maintenance</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_9" model="fleet.service.type">
|
||||
<field name="name">Assistance</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_10" model="fleet.service.type">
|
||||
<field name="name">Replacement Vehicle</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_11" model="fleet.service.type">
|
||||
<field name="name">Management Fee</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_12" model="fleet.service.type">
|
||||
<field name="name">Rent (Excluding VAT)</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_13" model="fleet.service.type">
|
||||
<field name="name">Entry into service tax</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_14" model="fleet.service.type">
|
||||
<field name="name">Total expenses (Excluding VAT)</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_15" model="fleet.service.type">
|
||||
<field name="name">Residual value (Excluding VAT)</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_16" model="fleet.service.type">
|
||||
<field name="name">Options</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_17" model="fleet.service.type">
|
||||
<field name="name">Emissions</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_18" model="fleet.service.type">
|
||||
<field name="name">Touring Assistance</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_service_19" model="fleet.service.type">
|
||||
<field name="name">Residual value in %</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_1" model="fleet.service.type">
|
||||
<field name="name">A/C Compressor Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_2" model="fleet.service.type">
|
||||
<field name="name">A/C Condenser Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_3" model="fleet.service.type">
|
||||
<field name="name">A/C Diagnosis</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_4" model="fleet.service.type">
|
||||
<field name="name">A/C Evaporator Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_5" model="fleet.service.type">
|
||||
<field name="name">A/C Recharge</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_6" model="fleet.service.type">
|
||||
<field name="name">Air Filter Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_7" model="fleet.service.type">
|
||||
<field name="name">Alternator Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_8" model="fleet.service.type">
|
||||
<field name="name">Ball Joint Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_9" model="fleet.service.type">
|
||||
<field name="name">Battery Inspection</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_10" model="fleet.service.type">
|
||||
<field name="name">Battery Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_11" model="fleet.service.type">
|
||||
<field name="name">Brake Caliper Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_12" model="fleet.service.type">
|
||||
<field name="name">Brake Inspection</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_13" model="fleet.service.type">
|
||||
<field name="name">Brake Pad(s) Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_14" model="fleet.service.type">
|
||||
<field name="name">Car Wash</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_15" model="fleet.service.type">
|
||||
<field name="name">Catalytic Converter Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_16" model="fleet.service.type">
|
||||
<field name="name">Charging System Diagnosis</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_17" model="fleet.service.type">
|
||||
<field name="name">Door Window Motor/Regulator Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_18" model="fleet.service.type">
|
||||
<field name="name">Engine Belt Inspection</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_19" model="fleet.service.type">
|
||||
<field name="name">Engine Coolant Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_20" model="fleet.service.type">
|
||||
<field name="name">Engine/Drive Belt(s) Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_21" model="fleet.service.type">
|
||||
<field name="name">Exhaust Manifold Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_22" model="fleet.service.type">
|
||||
<field name="name">Fuel Injector Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_23" model="fleet.service.type">
|
||||
<field name="name">Fuel Pump Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_24" model="fleet.service.type">
|
||||
<field name="name">Head Gasket(s) Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_25" model="fleet.service.type">
|
||||
<field name="name">Heater Blower Motor Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_26" model="fleet.service.type">
|
||||
<field name="name">Heater Control Valve Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_27" model="fleet.service.type">
|
||||
<field name="name">Heater Core Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_28" model="fleet.service.type">
|
||||
<field name="name">Heater Hose Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_29" model="fleet.service.type">
|
||||
<field name="name">Ignition Coil Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_30" model="fleet.service.type">
|
||||
<field name="name">Intake Manifold Gasket Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_31" model="fleet.service.type">
|
||||
<field name="name">Oil Change</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_32" model="fleet.service.type">
|
||||
<field name="name">Oil Pump Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_33" model="fleet.service.type">
|
||||
<field name="name">Other Maintenance</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_34" model="fleet.service.type">
|
||||
<field name="name">Oxygen Sensor Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_35" model="fleet.service.type">
|
||||
<field name="name">Power Steering Hose Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_36" model="fleet.service.type">
|
||||
<field name="name">Power Steering Pump Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_37" model="fleet.service.type">
|
||||
<field name="name">Radiator Repair</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_38" model="fleet.service.type">
|
||||
<field name="name">Resurface Rotors</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_39" model="fleet.service.type">
|
||||
<field name="name">Rotate Tires</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_40" model="fleet.service.type">
|
||||
<field name="name">Rotor Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_41" model="fleet.service.type">
|
||||
<field name="name">Spark Plug Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_42" model="fleet.service.type">
|
||||
<field name="name">Starter Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_43" model="fleet.service.type">
|
||||
<field name="name">Thermostat Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_44" model="fleet.service.type">
|
||||
<field name="name">Tie Rod End Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_45" model="fleet.service.type">
|
||||
<field name="name">Tire Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_46" model="fleet.service.type">
|
||||
<field name="name">Tire Service</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_47" model="fleet.service.type">
|
||||
<field name="name">Transmission Filter Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_48" model="fleet.service.type">
|
||||
<field name="name">Transmission Fluid Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_49" model="fleet.service.type">
|
||||
<field name="name">Transmission Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_50" model="fleet.service.type">
|
||||
<field name="name">Water Pump Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_51" model="fleet.service.type">
|
||||
<field name="name">Wheel Alignment</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_52" model="fleet.service.type">
|
||||
<field name="name">Wheel Bearing Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_53" model="fleet.service.type">
|
||||
<field name="name">Windshield Wiper(s) Replacement</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="type_contract_omnium" model="fleet.service.type">
|
||||
<field name="name">Omnium</field>
|
||||
<field name="category">contract</field>
|
||||
</record>
|
||||
|
||||
<record id="type_contract_leasing" model="fleet.service.type">
|
||||
<field name="name">Leasing</field>
|
||||
<field name="category">contract</field>
|
||||
</record>
|
||||
|
||||
<record id="type_contract_repairing" model="fleet.service.type">
|
||||
<field name="name">Repairing</field>
|
||||
<field name="category">both</field>
|
||||
</record>
|
||||
|
||||
<record id="type_service_refueling" model="fleet.service.type">
|
||||
<field name="name">Refueling</field>
|
||||
<field name="category">service</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_junior" model="fleet.vehicle.tag" >
|
||||
<field name="name">Junior</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_senior" model="fleet.vehicle.tag" >
|
||||
<field name="name">Senior</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_leasing" model="fleet.vehicle.tag" >
|
||||
<field name="name">Employee Car</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_purchased" model="fleet.vehicle.tag" >
|
||||
<field name="name">Purchased</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_compact" model="fleet.vehicle.tag" >
|
||||
<field name="name">Compact</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_sedan" model="fleet.vehicle.tag" >
|
||||
<field name="name">Sedan</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_convertible" model="fleet.vehicle.tag" >
|
||||
<field name="name">Convertible</field>
|
||||
</record>
|
||||
|
||||
<record id="vehicle_tag_break" model="fleet.vehicle.tag" >
|
||||
<field name="name">Break</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,907 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model='ir.ui.view' id='fleet_vehicle_model_form'>
|
||||
<field name="name">fleet.vehicle.model.form</field>
|
||||
<field name="model">fleet.vehicle.model</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Model" version="7.0">
|
||||
<sheet>
|
||||
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="brand" on_change="on_change_brand(brand)"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="modelname" />
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Vendors">
|
||||
<field name="vendors" widget="many2many_kanban"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model='ir.ui.view' id='fleet_vehicle_model_tree'>
|
||||
<field name="name">fleet.vehicle.model.tree</field>
|
||||
<field name="model">fleet.vehicle.model</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Models" version="7.0">
|
||||
<field name="brand" />
|
||||
<field name="modelname" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_model_act'>
|
||||
<field name="name">Vehicle Model</field>
|
||||
<field name="res_model">fleet.vehicle.model</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new model.
|
||||
</p><p>
|
||||
You can define several models (e.g. A3, A4) for each brand (Audi).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_model_brand_tree'>
|
||||
<field name="name">fleet.vehicle.model.brand.tree</field>
|
||||
<field name="model">fleet.vehicle.model.brand</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Model Brand" version="7.0">
|
||||
<field name="name" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_model_brand_form'>
|
||||
<field name="name">fleet.vehicle.model.brand.form</field>
|
||||
<field name="model">fleet.vehicle.model.brand</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Model Brand" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<div>
|
||||
<field name="image_medium" widget="image" class="oe_left oe_avatar"/>
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="name" class="oe_inline" />
|
||||
</h1>
|
||||
</div>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_model_brand_kanban'>
|
||||
<field name="name">fleet.vehicle.model.brandkanban</field>
|
||||
<field name="model">fleet.vehicle.model.brand</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<field name="name" />
|
||||
<field name="image" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_vignette oe_semantic_html_override">
|
||||
<a type="open" href="#" class="oe_kanban_action oe_kanban_action_a">
|
||||
<img t-att-src="kanban_image('fleet.vehicle.model.brand', 'image_small', record.id.value)" class="oe_employee_picture"/>
|
||||
</a>
|
||||
<div style="text-align:center;">
|
||||
<h4 class="oe_partner_heading">
|
||||
<a type="open">
|
||||
<field name="name"/>
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('.oe_picture').load(function() { if($(this).width() > $(this).height()) { $(this).addClass('oe_employee_picture_wide') } });
|
||||
</script>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_model_brand_act'>
|
||||
<field name="name">Model brand of Vehicle</field>
|
||||
<field name="res_model">fleet.vehicle.model.brand</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new brand.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_state_tree'>
|
||||
<field name="name">fleet.vehicle.state.tree</field>
|
||||
<field name="model">fleet.vehicle.state</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="State" version="7.0" editable="bottom">
|
||||
<field name="sequence" widget="handler" invisible="1"/>
|
||||
<field name="name" />
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_state_act'>
|
||||
<field name="name">States of Vehicle</field>
|
||||
<field name="res_model">fleet.vehicle.state</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a vehicule status.
|
||||
</p><p>
|
||||
You can customize available status to track the evolution of
|
||||
each vehicule. Example: Active, Being Repaired, Sold.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Fleet" id="menu_root" sequence="70" />
|
||||
<menuitem name="Configuration" parent="menu_root" id="fleet_configuration" sequence="3" />
|
||||
<menuitem action="fleet_vehicle_model_act" parent="fleet_configuration" id="fleet_vehicle_model_menu" groups="base.group_no_one"/>
|
||||
<menuitem action="fleet_vehicle_model_brand_act" parent="fleet_configuration" id="fleet_vehicle_model_brand_menu" groups="base.group_no_one"/>
|
||||
<menuitem action="fleet_vehicle_state_act" parent="fleet_configuration" id="fleet_vehicle_state_menu" />
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_form'>
|
||||
<field name="name">fleet.vehicle.form</field>
|
||||
<field name="model">fleet.vehicle</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Vehicle" version="7.0">
|
||||
<header>
|
||||
<field name="state" widget="statusbar" clickable="True" />
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="image_medium" widget='image' class="oe_left oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
<label for="model_id" class="oe_edit_only"/>
|
||||
<h1>
|
||||
<field name="model_id" class="oe_inline" on_change="on_change_model(model_id)"/>
|
||||
</h1>
|
||||
<label for="license_plate" class="oe_edit_only"/>
|
||||
<h2>
|
||||
<field name="license_plate" class="oe_inline"/>
|
||||
</h2>
|
||||
<label for="tag_ids" class="oe_edit_only"/>
|
||||
<field name="tag_ids" widget="many2many_tags" />
|
||||
</div>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_contract_act'}" string="Contracts" help="show the contract for this vehicle" />
|
||||
<button name="act_show_log_cost" type="object" string="Costs" help="show all the costs for this vehicle" />
|
||||
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_services_act'}" string="Services" help="show the services logs for this vehicle" />
|
||||
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_log_fuel_act'}" string="Fuel Logs" help="show the fuel logs for this vehicle" />
|
||||
<button name="return_action_to_open" type="object" context="{'xml_id':'fleet_vehicle_odometer_act'}" string="Odometer Logs" help="show the odometer logs for this vehicle" />
|
||||
</div>
|
||||
<group col="2" string="General Properties">
|
||||
<group >
|
||||
<field name="driver" />
|
||||
<field name="location" />
|
||||
<field name="vin_sn" />
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group >
|
||||
<label for="odometer" />
|
||||
<div>
|
||||
<field name="odometer" class="oe_inline"/>
|
||||
<field name="odometer_unit" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="acquisition_date" />
|
||||
<field name="car_value" />
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group string="Additional Properties">
|
||||
<field name="seats" />
|
||||
<field name="doors" />
|
||||
<field name="color" />
|
||||
</group>
|
||||
<group string="Engine Options">
|
||||
<field name="transmission" />
|
||||
<field name="fuel_type" />
|
||||
<field name="co2" />
|
||||
<field name="horsepower" />
|
||||
<field name="horsepower_tax" />
|
||||
<field name="power" />
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_ids" widget="mail_thread" options='{"thread_level": 1}'/>
|
||||
<field name="message_follower_ids" widget="mail_followers"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model='ir.ui.view' id='fleet_vehicle_tree'>
|
||||
<field name="name">fleet.vehicle.tree</field>
|
||||
<field name="model">fleet.vehicle</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Vehicle" version="7.0" colors="orange:contract_renewal_due_soon and not contract_renewal_overdue;red:contract_renewal_overdue">
|
||||
<field name="license_plate" />
|
||||
<field name="model_id" />
|
||||
<field name="driver" />
|
||||
<field name="vin_sn" />
|
||||
<field name="acquisition_date" />
|
||||
<field name="state"/>
|
||||
<field name="odometer" />
|
||||
<field name="odometer_unit" />
|
||||
<field name="contract_renewal_due_soon" invisible="1"/>
|
||||
<field name="contract_renewal_overdue" invisible="1" />
|
||||
<field name="contract_renewal_total" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_search">
|
||||
<field name="name">fleet.vehicle.search</field>
|
||||
<field name="model">fleet.vehicle</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="All vehicles">
|
||||
<field name="name" filter_domain="['|', ('name','ilike',self), ('license_plate','ilike',self)]" string="Vehicle"/>
|
||||
<field name="driver"/>
|
||||
<field name="tag_ids"/>
|
||||
<field name="location"/>
|
||||
<field name="state" />
|
||||
<field name="state" />
|
||||
<filter name="alert_true" domain="['|',('contract_renewal_due_soon','>',0),('contract_renewal_overdue','>',0)]" string="Has Alert(s)"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_kanban'>
|
||||
<field name="name">fleet.vehicle.kanban</field>
|
||||
<field name="model">fleet.vehicle</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<field name="license_plate" />
|
||||
<field name="model_id" />
|
||||
<field name="driver" />
|
||||
<field name="location" />
|
||||
<field name="state" />
|
||||
|
||||
<field name="image" />
|
||||
<field name="tag_ids" />
|
||||
<field name="contract_renewal_due_soon" />
|
||||
<field name="contract_renewal_overdue" />
|
||||
<field name="contract_renewal_name" />
|
||||
<field name="contract_renewal_total" />
|
||||
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div class="oe_kanban_vignette oe_semantic_html_override">
|
||||
<a type="open" href="#" class="oe_kanban_action oe_kanban_action_a">
|
||||
<img t-att-src="kanban_image('fleet.vehicle', 'image_small', record.id.value)"/>
|
||||
</a>
|
||||
<div class="oe_kanban_details">
|
||||
<h4 class="oe_partner_heading">
|
||||
<a type="open">
|
||||
<field name="license_plate"/><br/>
|
||||
<field name="model_id" />
|
||||
</a>
|
||||
</h4>
|
||||
<t t-if="record.contract_renewal_due_soon.raw_value and !record.contract_renewal_overdue.raw_value">
|
||||
<a data-type="object" data-name="return_action_to_open" href="#" class="oe_kanban_action oe_kanban_action_a" data-context='{"xml_id":"fleet_vehicle_log_contract_act"}'>
|
||||
<span class="oe_tag oe_kanban_color_3"><field name="contract_renewal_name" />
|
||||
<t t-if="record.contract_renewal_total.raw_value > 0"> and <field name="contract_renewal_total" /> other(s) </t>
|
||||
</span>
|
||||
</a>
|
||||
</t>
|
||||
|
||||
<t t-if="record.contract_renewal_overdue.raw_value">
|
||||
<a data-type="object" data-name="return_action_to_open" href="#" class="oe_kanban_action oe_kanban_action_a" data-context='{"xml_id":"fleet_vehicle_log_contract_act"}'>
|
||||
<span class="oe_tag oe_kanban_color_2"><field name="contract_renewal_name" />
|
||||
<t t-if="record.contract_renewal_total.raw_value > 0"> and <field name="contract_renewal_total" /> other(s) </t>
|
||||
</span>
|
||||
</a>
|
||||
</t>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<t t-if="record.driver.raw_value"><field name="driver"/></t>
|
||||
</li>
|
||||
<li>
|
||||
<t t-if="record.location.raw_value"><field name="location"/></t>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="oe_kanban_partner_categories">
|
||||
<span class="oe_kanban_list_many2many">
|
||||
<div modifiers="{}" name="tag_ids" class="oe_form_field oe_tags" model="fleet.vehicle.tag" t-att-data="record.tag_ids.raw_value" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_act'>
|
||||
<field name="name">Vehicles</field>
|
||||
<field name="res_model">fleet.vehicle</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">kanban,tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new vehicle.
|
||||
</p><p>
|
||||
You will be able to manage your fleet by keeping track of the
|
||||
contracts, services, fixed and recurring costs, odometers and
|
||||
fuel logs associated to each vehicle.
|
||||
</p><p>
|
||||
OpenERP will warn you when services or contract have to be
|
||||
renewed.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Vehicles" parent="menu_root" id="fleet_vehicles" sequence="2" />
|
||||
<menuitem action="fleet_vehicle_act" parent="fleet_vehicles" id="fleet_vehicle_menu" />
|
||||
|
||||
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_contract_form'>
|
||||
<field name="name">fleet.vehicle.log_contract.form</field>
|
||||
<field name="model">fleet.vehicle.log.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contract logs" version="7.0">
|
||||
<header>
|
||||
<button modifiers="{'invisible': [['state', '=', 'closed']]}" name="contract_close" states="open" type="object" class="oe_highlight" string="Terminate Contract"/>
|
||||
<button modifiers="{'invisible': [['state', '=', 'closed']]}" name="contract_close" states="toclose" type="object" class="oe_highlight" string="Terminate Contract"/>
|
||||
<button modifiers="{'invisible': [['state', 'not in', ['closed']]]}" name="contract_open" states="closed" type="object" class="oe_highlight" string="Set Contract In Progress"/>
|
||||
<button class="oe_highlight" name="act_renew_contract" type="object" string="Renew Contract" help="Create a new contract automatically with all the same informations except for the date that will start at the end of current contract" />
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<sheet>
|
||||
<group col="2">
|
||||
<group string="Contract details">
|
||||
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
|
||||
<field name="cost_subtype" required="1" domain="['|',('category','=','contract'),('category','=','both')]"/>
|
||||
<field name="amount" string="Activation Cost"/>
|
||||
<label for="cost_generated"/>
|
||||
<div>
|
||||
<field name="cost_generated" class="oe_inline" attrs="{'invisible': [('cost_frequency','=','no')]}" />
|
||||
<field name="cost_frequency" class="oe_inline" />
|
||||
</div>
|
||||
</group>
|
||||
<group string="Odometer details">
|
||||
<label for="odometer"/>
|
||||
<div>
|
||||
<field name="odometer" class="oe_inline"/>
|
||||
<field name="odometer_unit" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="date" string="Invoice Date"/>
|
||||
<field name="start_date"/>
|
||||
<field name="expiration_date" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="insurer_id" />
|
||||
<field name="purchaser_id" />
|
||||
<field name="ins_ref" />
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Included Services">
|
||||
<group>
|
||||
<field name="cost_ids" context="{'vehicle_id': vehicle_id}" nolabel="1" on_change="on_change_indic_cost(cost_ids)">
|
||||
<tree version="7.0" editable="bottom">
|
||||
<field name="cost_subtype" string="Service" domain="[('category','=','service')]"/>
|
||||
<field name="amount" sum="Price" string="Indicative Cost" />
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
</group>
|
||||
<div class="oe_right"><group><field name="sum_cost" string="Indicative Costs Total"/></group></div>
|
||||
</page>
|
||||
<page string="Generated Costs">
|
||||
<group>
|
||||
<field name="generated_cost_ids" context="{'vehicle_id': vehicle_id}" nolabel="1" sum="amount">
|
||||
<tree version="7.0" editable="bottom" >
|
||||
<field name="date" />
|
||||
<field name="amount" sum="amount"/>
|
||||
</tree>
|
||||
|
||||
</field>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<group string="Terms and Conditions">
|
||||
<field name="notes" nolabel="1" placeholder="Write here all other information relative to this contract" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
|
||||
id="act_renew_contract"
|
||||
name="Renew Contract"
|
||||
res_model="fleet.vehicle.log.contract"
|
||||
src_model="fleet.vehicle.log.contract"
|
||||
view_mode="form"
|
||||
view_type="form"
|
||||
/>
|
||||
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_contract_tree'>
|
||||
<field name="name">fleet.vehicle.log.contract.tree</field>
|
||||
<field name="model">fleet.vehicle.log.contract</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Contract logs" version="7.0" colors="orange:days_left>0 and days_left<15;red:days_left==0;grey:state=='closed'">
|
||||
<field name="start_date" />
|
||||
<field name="expiration_date" />
|
||||
<field name="days_left" invisible="1"/>
|
||||
<field name="vehicle_id" />
|
||||
<field name="cost_subtype"/>
|
||||
<field name="insurer_id" />
|
||||
<field name="amount" string="Activation Cost"/>
|
||||
<field name="cost_generated"/>
|
||||
<field name="cost_frequency"/>
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_log_contract_graph">
|
||||
<field name="name">fleet.vehicle.log.contract.graph</field>
|
||||
<field name="model">fleet.vehicle.log.contract</field>
|
||||
<!--<field name="type">graph</field>-->
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Contract Costs Per Month">
|
||||
<field name="date" />
|
||||
<field name="cost_amount" operator="+"/>
|
||||
<field name="vehicle_id" group="True"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_log_contract_act'>
|
||||
<field name="name">Vehicles Contracts</field>
|
||||
<field name="res_model">fleet.vehicle.log.contract</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new contract.
|
||||
</p><p>
|
||||
Manage all your contracts (leasing, insurances, etc.) with
|
||||
their related services, costs. OpenERP will automatically warn
|
||||
you when some contracts have to be renewed.
|
||||
</p><p>
|
||||
Each contract (e.g.: leasing) may include several services
|
||||
(reparation, insurances, periodic maintenance).
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_log_contract_act" parent="fleet_vehicles" id="fleet_vehicle_log_contract_menu" />
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_odometer_form'>
|
||||
<field name="name">fleet.vehicle.odometer.form</field>
|
||||
<field name="model">fleet.vehicle.odometer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Odometer Logs" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
|
||||
<div>
|
||||
<field name="value" class="oe_inline"/>
|
||||
<field name="unit" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="date" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_odometer_tree'>
|
||||
<field name="name">fleet.vehicle.odometer.tree</field>
|
||||
<field name="model">fleet.vehicle.odometer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Odometer Logs" version="7.0" editable="bottom">
|
||||
<field name="date" />
|
||||
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
|
||||
<field name="value" />
|
||||
<field name="unit" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<!--
|
||||
<record model='ir.ui.view' id='fleet_vehicle_odometer_search'>
|
||||
<field name="name">fleet.vehicle.odometer.search</field>
|
||||
<field name="model">fleet.vehicle.odometer</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Vehicles odometers" >
|
||||
<field name="vehicle_id" />
|
||||
<field name="value"/>
|
||||
<field name="unit"/>
|
||||
<field name="date"/>
|
||||
<filter name="groupby_vehicle" context="{'group_by' : 'vehicle_id'}" string="Vehicle"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_odometer_graph">
|
||||
<field name="name">fleet.vehicle.odometer.graph</field>
|
||||
<field name="model">fleet.vehicle.odometer</field>
|
||||
<!--<field name="type">graph</field>-->
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Odometer Values Per Month">
|
||||
<field name="date" />
|
||||
<field name="value" operator="+"/>
|
||||
<field name="vehicle_id" group="True"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_odometer_act'>
|
||||
<field name="name">Vehicles Odometer</field>
|
||||
<field name="res_model">fleet.vehicle.odometer</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="context">{"search_default_groupby_vehicle" : True}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here you can add various odometer entries for all vehicles.
|
||||
You can also show odometer value for a particular vehicle using
|
||||
the search field.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_odometer_act" parent="fleet_vehicles" id="fleet_vehicle_odometer_menu" />
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_fuel_form'>
|
||||
<field name="name">fleet.vehicle.log.fuel.form</field>
|
||||
<field name="model">fleet.vehicle.log.fuel</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fuel Logs" version="7.0">
|
||||
<sheet>
|
||||
<group col="2">
|
||||
<group string="Vehicle Details">
|
||||
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
|
||||
</group>
|
||||
<group string="Refueling Details">
|
||||
<field name="liter" on_change="on_change_liter(liter,price_per_liter,amount)"/>
|
||||
<field name="price_per_liter" on_change="on_change_price_per_liter(liter,price_per_liter,amount)" />
|
||||
<field name="amount" on_change="on_change_amount(liter,price_per_liter,amount)"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group string="Odometer Details">
|
||||
<label for="odometer"/>
|
||||
<div>
|
||||
<field name="odometer" class="oe_inline"/>
|
||||
<field name="odometer_unit" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Additional Details">
|
||||
<field name="date" />
|
||||
<field name="purchaser_id" />
|
||||
<field name="inv_ref" />
|
||||
<field name="vendor_id" />
|
||||
</group>
|
||||
</group>
|
||||
<group string="Notes">
|
||||
<field nolabel="1" name="notes" placeholder="Write here any other information"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_fuel_tree'>
|
||||
<field name="name">fleet.vehicle.log.fuel.tree</field>
|
||||
<field name="model">fleet.vehicle.log.fuel</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fuel Logs">
|
||||
<field name="date" />
|
||||
<field name="vehicle_id" />
|
||||
<field name="odometer" invisible="1"/>
|
||||
<field name="odometer_unit" invisible="1"/>
|
||||
<field name="purchaser_id" />
|
||||
<field name="inv_ref" invisible="1"/>
|
||||
<field name="vendor_id" invisible="1"/>
|
||||
<field name="liter" />
|
||||
<field name="price_per_liter" invisible="1"/>
|
||||
<field name="amount" sum="Price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_log_fuel_graph">
|
||||
<field name="name">fleet.vehicle.log.fuel.graph</field>
|
||||
<field name="model">fleet.vehicle.log.fuel</field>
|
||||
<!--<field name="type">graph</field>-->
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Fuel Costs Per Month">
|
||||
<field name="date" />
|
||||
<field name="cost_amount" operator="+"/>
|
||||
<field name="vehicle_id" group="True"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_log_fuel_act'>
|
||||
<field name="name">Vehicles Fuel Logs</field>
|
||||
<field name="res_model">fleet.vehicle.log.fuel</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new fuel log.
|
||||
</p><p>
|
||||
Here you can add refuelling entries for all vehicles. You can
|
||||
also filter logs of a particular vehicle using the search
|
||||
field.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_log_fuel_act" parent="fleet_vehicles" id="fleet_vehicle_log_fuel_menu" />
|
||||
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_services_form'>
|
||||
<field name="name">fleet.vehicle.log.services.form</field>
|
||||
<field name="model">fleet.vehicle.log.services</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Services Logs" version="7.0">
|
||||
<sheet>
|
||||
<group col="2">
|
||||
<group string="Services Details">
|
||||
<field name="vehicle_id" on_change="on_change_vehicle(vehicle_id)"/>
|
||||
<field name="cost_subtype" string="Service Type" domain="['|',('category','=','service'),('category','=','both')]" required="1"/>
|
||||
<field name="amount" string="Price"/>
|
||||
</group>
|
||||
<group string="Odometer Details">
|
||||
<label for="odometer"/>
|
||||
<div>
|
||||
<field name="odometer" class="oe_inline"/>
|
||||
<field name="odometer_unit" class="oe_inline"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group string="Additional Details">
|
||||
<field name="date" />
|
||||
<field name="purchaser_id" />
|
||||
<field name="vendor_id" />
|
||||
<field name="inv_ref" />
|
||||
</group>
|
||||
</group>
|
||||
<group string="Included Services">
|
||||
<field name="cost_ids" nolabel="1">
|
||||
<tree string="Included Services" version="7.0" editable="bottom">
|
||||
<field name="cost_subtype" string="Service" domain="[('category','=','service')]"/>
|
||||
<field name="amount" sum="Price" string="Cost"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group string="Notes">
|
||||
<field nolabel="1" name="notes" placeholder="Write here any other information related to the service completed."/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_log_services_tree'>
|
||||
<field name="name">fleet.vehicle.log.services.tree</field>
|
||||
<field name="model">fleet.vehicle.log.services</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Services Logs">
|
||||
<field name="date" />
|
||||
<field name="vehicle_id" />
|
||||
<field name="cost_subtype"/>
|
||||
<field name="purchaser_id"/>
|
||||
<field name="vendor_id" />
|
||||
<field name="inv_ref" />
|
||||
<field name="notes" />
|
||||
<field name="amount" sum="Total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_log_services_graph">
|
||||
<field name="name">fleet.vehicle.log.services.graph</field>
|
||||
<field name="model">fleet.vehicle.log.services</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Services Costs Per Month">
|
||||
<field name="date" />
|
||||
<field name="cost_amount" operator="+"/>
|
||||
<field name="vehicle_id" group="True"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_log_services_act'>
|
||||
<field name="name">Vehicles Services Logs</field>
|
||||
<field name="res_model">fleet.vehicle.log.services</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new service entry.
|
||||
</p><p>
|
||||
OpenERP helps you keeping track of all the services done
|
||||
on your vehicle. Services can be of many type: occasional
|
||||
repair, fixed maintenance, etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_log_services_act" parent="fleet_vehicles" id="fleet_vehicle_log_services_menu" />
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_service_types_tree'>
|
||||
<field name="name">fleet.service.type.tree</field>
|
||||
<field name="model">fleet.service.type</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Service types" editable="bottom">
|
||||
<field name="name" />
|
||||
<field name="category"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_service_types_act'>
|
||||
<field name="name">Service Types</field>
|
||||
<field name="res_model">fleet.service.type</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new type of service.
|
||||
</p><p>
|
||||
Each service can used in contracts, as a standalone service or both.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_service_types_act" parent="fleet_configuration" id="fleet_vehicle_service_types_menu" groups="base.group_no_one"/>
|
||||
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_costs_tree'>
|
||||
<field name="name">fleet.vehicle.cost.tree</field>
|
||||
<field name="model">fleet.vehicle.cost</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Vehicles costs" >
|
||||
<field name="date"/>
|
||||
<field name="vehicle_id" />
|
||||
<field name="cost_type"/>
|
||||
<field name="cost_subtype"/>
|
||||
<field name="amount" sum="Total Cost"/>
|
||||
<field name="parent_id" invisible="1" />
|
||||
<field name="year" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_costs_search'>
|
||||
<field name="name">fleet.vehicle.cost.search</field>
|
||||
<field name="model">fleet.vehicle.cost</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Vehicles costs" >
|
||||
<field name="vehicle_id" />
|
||||
<field name="cost_subtype"/>
|
||||
<field name="year"/>
|
||||
<field name="date"/>
|
||||
<field name="parent_id"/>
|
||||
<filter name="parent_false" domain="[('parent_id','=',False)]" string="Effective Costs"/>
|
||||
<filter name="parent_true" domain="[('parent_id','!=',False)]" string="Indicative Costs"/>
|
||||
<group expand="1" string="Group By...">
|
||||
<filter name="groupby_year" context="{'group_by' : 'year'}" string="Year"/>
|
||||
<filter name="groupby_date" context="{'group_by' : 'date'}" string="Date"/>
|
||||
<filter name="groupby_cost_type" context="{'group_by' : 'cost_type'}" string="Cost Type"/>
|
||||
<filter name="groupby_cost_subtype" context="{'group_by' : 'cost_subtype'}" string="Cost Subtype"/>
|
||||
<filter name="groupby_vehicle_id" context="{'group_by' : 'vehicle_id'}" string="Vehicle"/>
|
||||
<filter name="groupby_parent_id" context="{'group_by' : 'parent_id'}" string="Parent"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.ui.view' id='fleet_vehicle_costs_form'>
|
||||
<field name="name">fleet.vehicle.cost.form</field>
|
||||
<field name="model">fleet.vehicle.cost</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Vehicle costs" version="7.0">
|
||||
<sheet>
|
||||
<group col="2" string="Cost Details">
|
||||
<group>
|
||||
<field name="vehicle_id" />
|
||||
<field name="cost_subtype"/>
|
||||
<field name="amount"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="parent_id"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="fleet_vehicle_costs_graph">
|
||||
<field name="name">fleet.vehicle.cost.graph</field>
|
||||
<field name="model">fleet.vehicle.cost</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Costs Per Month">
|
||||
<field name="date" />
|
||||
<field name="amount"/>
|
||||
<field name="vehicle_id" group="True"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model='ir.actions.act_window' id='fleet_vehicle_costs_act'>
|
||||
<field name="name">Vehicle Costs</field>
|
||||
<field name="res_model">fleet.vehicle.cost</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,graph</field>
|
||||
<field name="context">{"search_default_parent_false" : True, "search_default_groupby_vehicle_id" : True,}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new cost.
|
||||
</p><p>
|
||||
OpenERP helps you managing the costs for your different
|
||||
vehicles. Costs are created automatically from services,
|
||||
contracts (fixed or recurring) and fuel logs.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="fleet_vehicle_costs_act" parent="fleet_vehicles" id="fleet_vehicle_costs_menu" />
|
||||
<!--
|
||||
<record model='ir.ui.view' id='fleet_hr_employee_form'>
|
||||
<field name="name">fleet.hr.employee.form</field>
|
||||
<field name="model">hr.employee</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="hr.view_employee_form" />
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Vehicle">
|
||||
<group>
|
||||
<field name="vehicle_id" widget="many2many_tags"/>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="fleet.vehicle.model" id="citroen">
|
||||
<field name="name">Citroen</field>
|
||||
</record>
|
||||
|
||||
<record model="fleet.vehicle" id="stw_vehicle">
|
||||
<field name="name">240BTN</field>
|
||||
<field name="model_id" ref="citroen" />
|
||||
</record>
|
||||
-->
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,11 @@
|
|||
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
|
||||
fleet_vehicle_model_access_right,fleet_vehicle_model_access_right,model_fleet_vehicle_model,,1,1,1,1
|
||||
fleet_vehicle_tag_access_right,fleet_vehicle_tag_access_right,model_fleet_vehicle_tag,,1,1,1,1
|
||||
fleet_vehicle_state_access_right,fleet_vehicle_state_access_right,model_fleet_vehicle_state,,1,1,1,1
|
||||
fleet_vehicle_odometer_access_right,fleet_vehicle_odometer_access_right,model_fleet_vehicle_odometer,,1,1,1,1
|
||||
fleet_vehicle_model_brand_access_right,fleet_vehicle_model_brand_access_right,model_fleet_vehicle_model_brand,,1,1,1,1
|
||||
fleet_vehicle_access_right,fleet_vehicle_access_right,model_fleet_vehicle,,1,1,1,1
|
||||
fleet_vehicle_log_fuel_access_right,fleet_vehicle_log_fuel_access_right,model_fleet_vehicle_log_fuel,,1,1,1,1
|
||||
fleet_vehicle_log_services_access_right,fleet_vehicle_log_services_access_right,model_fleet_vehicle_log_services,,1,1,1,1
|
||||
fleet_vehicle_log_contract_access_right,fleet_vehicle_log_contract_access_right,model_fleet_vehicle_log_contract,,1,1,1,1
|
||||
fleet_service_type_access_right,fleet_service_type_access_right,model_fleet_service_type,,1,1,1,1
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,124 @@
|
|||
# Spanish translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-11-07 12:33+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-08 04:47+0000\n"
|
||||
"X-Generator: Launchpad (build 16232)\n"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:res.users,gmail_user:0
|
||||
msgid "Username"
|
||||
msgstr "Nombre de usuario"
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.actions.act_window,name:google_base_account.act_google_login_form
|
||||
msgid "Google Login"
|
||||
msgstr "Acceso de Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:29
|
||||
#, python-format
|
||||
msgid "Google Contacts Import Error!"
|
||||
msgstr "¡Error en la importacion de los contactos de Google!"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:res.users:0
|
||||
msgid " Synchronization "
|
||||
msgstr " Sincronización "
|
||||
|
||||
#. module: google_base_account
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr "¡No puede tener dos usuarios con el mismo identificador!"
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:75
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "Google login"
|
||||
msgstr "Acceso Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.model,name:google_base_account.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr "Usuarios"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:google.login,password:0
|
||||
msgid "Google Password"
|
||||
msgstr "Contraseña de Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancelar"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:res.users:0
|
||||
msgid "Google Account"
|
||||
msgstr "Cuenta de Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:google.login,user:0
|
||||
msgid "Google Username"
|
||||
msgstr "Usuario de Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:29
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please install gdata-python-client from http://code.google.com/p/gdata-"
|
||||
"python-client/downloads/list"
|
||||
msgstr ""
|
||||
"Por favor, instale gdata-python-client de http://code.google.com/p/gdata-"
|
||||
"python-client/downloads/list o desde el administrador de paquetes de su "
|
||||
"distribución"
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.model,name:google_base_account.model_google_login
|
||||
msgid "Google Contact"
|
||||
msgstr "Contacto Google"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "_Login"
|
||||
msgstr "Iniciar _sesión"
|
||||
|
||||
#. module: google_base_account
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr ""
|
||||
"La compañía seleccionada no está entre las companías permitidas para este "
|
||||
"usuario"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:res.users,gmail_password:0
|
||||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:75
|
||||
#, python-format
|
||||
msgid "Authentication fail check the user and password !"
|
||||
msgstr "Fallo en la autenticación. ¡Compruebe el usuario y la contraseña!"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "ex: user@gmail.com"
|
||||
msgstr "ejemplo: usuario@gmail.com"
|
|
@ -0,0 +1,119 @@
|
|||
# Mongolian translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-11-08 03:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Mongolian <mn@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-09 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16250)\n"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:res.users,gmail_user:0
|
||||
msgid "Username"
|
||||
msgstr "Хэрэглэгчийн нэр"
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.actions.act_window,name:google_base_account.act_google_login_form
|
||||
msgid "Google Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:29
|
||||
#, python-format
|
||||
msgid "Google Contacts Import Error!"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:res.users:0
|
||||
msgid " Synchronization "
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: sql_constraint:res.users:0
|
||||
msgid "You can not have two users with the same login !"
|
||||
msgstr "Ижил нэвтрэх нэртэй хоёр хэрэглэгч байж болохгүй!"
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:75
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Алдаа"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "Google login"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.model,name:google_base_account.model_res_users
|
||||
msgid "res.users"
|
||||
msgstr "res.users"
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:google.login,password:0
|
||||
msgid "Google Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "_Cancel"
|
||||
msgstr "_Цуцлах"
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:res.users:0
|
||||
msgid "Google Account"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:google.login,user:0
|
||||
msgid "Google Username"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:29
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Please install gdata-python-client from http://code.google.com/p/gdata-"
|
||||
"python-client/downloads/list"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: model:ir.model,name:google_base_account.model_google_login
|
||||
msgid "Google Contact"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "_Login"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: constraint:res.users:0
|
||||
msgid "The chosen company is not in the allowed companies for this user"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: field:res.users,gmail_password:0
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: code:addons/google_base_account/wizard/google_login.py:75
|
||||
#, python-format
|
||||
msgid "Authentication fail check the user and password !"
|
||||
msgstr ""
|
||||
|
||||
#. module: google_base_account
|
||||
#: view:google.login:0
|
||||
msgid "ex: user@gmail.com"
|
||||
msgstr ""
|
|
@ -16,9 +16,9 @@ var _t = instance.web._t,
|
|||
var view = self.getParent();
|
||||
var ids = ( view.fields_view.type != "form" )? view.groups.get_selection().ids : [ view.datarecord.id ];
|
||||
if( !_.isEmpty(ids) ){
|
||||
view.sidebar_context().then(function (context) {
|
||||
view.sidebar_context().done(function (context) {
|
||||
var ds = new instance.web.DataSet(this, 'ir.attachment', context);
|
||||
ds.call('google_doc_get', [view.dataset.model, ids, context]).then(function(r) {
|
||||
ds.call('google_doc_get', [view.dataset.model, ids, context]).done(function(r) {
|
||||
if (r == 'False') {
|
||||
var params = {
|
||||
error: response,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
'version': '1.1',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 12,
|
||||
'sequence': 21,
|
||||
'website': 'http://www.openerp.com',
|
||||
'summary': 'Jobs, Departments, Employees Details',
|
||||
'description': """
|
||||
|
|
|
@ -57,7 +57,7 @@ openerp.hr_attendance = function (instance) {
|
|||
var employee = new instance.web.DataSetSearch(self, 'hr.employee', self.session.user_context, [
|
||||
['user_id', '=', self.session.uid]
|
||||
]);
|
||||
return employee.read_slice(['id', 'name', 'state', 'last_sign', 'attendance_access']).pipe(function (res) {
|
||||
return employee.read_slice(['id', 'name', 'state', 'last_sign', 'attendance_access']).then(function (res) {
|
||||
if (_.isEmpty(res) )
|
||||
return;
|
||||
if (res[0].attendance_access == false){
|
||||
|
@ -75,7 +75,7 @@ openerp.hr_attendance = function (instance) {
|
|||
do_update: function () {
|
||||
this._super();
|
||||
var self = this;
|
||||
this.update_promise = this.update_promise.then(function () {
|
||||
this.update_promise = this.update_promise.done(function () {
|
||||
if (self.attendanceslider)
|
||||
return;
|
||||
self.attendanceslider = new instance.hr_attendance.AttendanceSlider(self);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
'version': '0.1',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 31,
|
||||
'website': 'http://www.openerp.com',
|
||||
'summary': 'Periodical Evaluations, Appraisals, Surveys',
|
||||
'images': ['images/hr_evaluation_analysis.jpeg','images/hr_evaluation.jpeg'],
|
||||
|
|
|
@ -291,6 +291,7 @@ survey_request()
|
|||
class hr_evaluation_interview(osv.osv):
|
||||
_name = 'hr.evaluation.interview'
|
||||
_inherits = {'survey.request': 'request_id'}
|
||||
_inherit = 'mail.thread'
|
||||
_rec_name = 'request_id'
|
||||
_description = 'Appraisal Interview'
|
||||
_columns = {
|
||||
|
|
|
@ -266,7 +266,7 @@
|
|||
Each employee may be assigned an Appraisal Plan. Such a plan
|
||||
defines the frequency and the way you manage your periodic
|
||||
personnel evaluation. You will be able to define steps and
|
||||
attach interviews to each step. OpenERP manages all kind of
|
||||
attach interviews to each step. OpenERP manages all kinds of
|
||||
evaluations: bottom-up, top-down, self-evaluation and final
|
||||
evaluation by the manager.
|
||||
</p>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
'name': 'Expense Management',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 30,
|
||||
'sequence': 29,
|
||||
'summary': 'Expenses Validation, Invoicing',
|
||||
'description': """
|
||||
Manage expenses by Employees
|
||||
|
|
|
@ -123,8 +123,8 @@
|
|||
<separator string="Notes"/>
|
||||
<field name="note" placeholder="Free Notes"/>
|
||||
</div>
|
||||
<group class="oe_subtotal_footer">
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
|
||||
<group class="oe_subtotal_footer oe_right">
|
||||
<field name="amount" widget="monetary" options="{'currency_field': 'currency_id'}" class="oe_subtotal_footer_separator"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -211,8 +211,7 @@
|
|||
<field name="search_view_id" ref="product.product_search_form_view"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_product_hr_config_expense" name="Expenses" parent="hr.menu_hr_configuration"/>
|
||||
<menuitem id="menu_hr_product" name="Products" parent="menu_product_hr_config_expense" action="hr_expense_product"/>
|
||||
<menuitem id="menu_hr_product" name="Type of Expenses" parent="hr.menu_hr_configuration" action="hr_expense_product"/>
|
||||
<menuitem id="next_id_49" name="Expenses" sequence="15" parent="hr.menu_hr_root"/>
|
||||
<menuitem action="expense_all" id="menu_expense_all" name="Expenses" parent="next_id_49"/>
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
'version': '1.5',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 28,
|
||||
'sequence': 27,
|
||||
'summary': 'Holidays, Allocation and Leave Requests',
|
||||
'website': 'http://www.openerp.com',
|
||||
'description': """
|
||||
|
|
|
@ -27,6 +27,7 @@ from operator import itemgetter
|
|||
|
||||
import math
|
||||
import netsvc
|
||||
import tools
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
|
||||
|
@ -112,6 +113,13 @@ class hr_holidays(osv.osv):
|
|||
result[hol.id] = hol.number_of_days_temp
|
||||
return result
|
||||
|
||||
def _check_date(self, cr, uid, ids):
|
||||
for holiday in self.browse(cr, uid, ids):
|
||||
holiday_ids = self.search(cr, uid, [('date_from', '<=', holiday.date_to), ('date_to', '>=', holiday.date_from), ('employee_id', '=', holiday.employee_id.id), ('id', '<>', holiday.id)])
|
||||
if holiday_ids:
|
||||
return False
|
||||
return True
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=64),
|
||||
'state': fields.selection([('draft', 'To Submit'), ('cancel', 'Cancelled'),('confirm', 'To Approve'), ('refuse', 'Refused'), ('validate1', 'Second Approval'), ('validate', 'Approved')],
|
||||
|
@ -145,12 +153,16 @@ class hr_holidays(osv.osv):
|
|||
'user_id': lambda obj, cr, uid, context: uid,
|
||||
'holiday_type': 'employee'
|
||||
}
|
||||
_constraints = [
|
||||
(_check_date, 'You can not have 2 leaves that overlaps on same day!', ['date_from','date_to']),
|
||||
]
|
||||
|
||||
_sql_constraints = [
|
||||
('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))", "The employee or employee category of this request is missing."),
|
||||
('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be before the end date !"),
|
||||
('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0 !"),
|
||||
('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be anterior to the end date."),
|
||||
('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0."),
|
||||
]
|
||||
|
||||
|
||||
def _create_resource_leave(self, cr, uid, leaves, context=None):
|
||||
'''This method will create entry in resource calendar leave object at the time of holidays validated '''
|
||||
obj_res_leave = self.pool.get('resource.calendar.leaves')
|
||||
|
@ -182,6 +194,13 @@ class hr_holidays(osv.osv):
|
|||
}
|
||||
return result
|
||||
|
||||
def onchange_employee(self, cr, uid, ids, employee_id):
|
||||
result = {'value': {'department_id': False}}
|
||||
if employee_id:
|
||||
employee = self.pool.get('hr.employee').browse(cr, uid, employee_id)
|
||||
result['value'] = {'department_id': employee.department_id.id}
|
||||
return result
|
||||
|
||||
# TODO: can be improved using resource calendar method
|
||||
def _get_number_of_days(self, date_from, date_to):
|
||||
"""Returns a float equals to the timedelta between two dates given as string."""
|
||||
|
@ -196,22 +215,62 @@ class hr_holidays(osv.osv):
|
|||
def unlink(self, cr, uid, ids, context=None):
|
||||
for rec in self.browse(cr, uid, ids, context=context):
|
||||
if rec.state not in ['draft', 'cancel', 'confirm']:
|
||||
raise osv.except_osv(_('Warning!'),_('You cannot delete a leave which is in %s state!')%(rec.state))
|
||||
raise osv.except_osv(_('Warning!'),_('You cannot delete a leave which is in %s state.')%(rec.state))
|
||||
return super(hr_holidays, self).unlink(cr, uid, ids, context)
|
||||
|
||||
def onchange_date_from(self, cr, uid, ids, date_to, date_from):
|
||||
result = {}
|
||||
if date_to and date_from:
|
||||
"""
|
||||
If there are no date set for date_to, automatically set one 8 hours later than
|
||||
the date_from.
|
||||
Also update the number_of_days.
|
||||
"""
|
||||
# date_to has to be greater than date_from
|
||||
if (date_from and date_to) and (date_from > date_to):
|
||||
raise osv.except_osv(_('Warning!'),_('The start date must be anterior to the end date.'))
|
||||
|
||||
result = {'value': {}}
|
||||
|
||||
# No date_to set so far: automatically compute one 8 hours later
|
||||
if date_from and not date_to:
|
||||
date_to_with_delta = datetime.datetime.strptime(date_from, tools.DEFAULT_SERVER_DATETIME_FORMAT) + datetime.timedelta(hours=8)
|
||||
result['value']['date_to'] = str(date_to_with_delta)
|
||||
|
||||
# Compute and update the number of days
|
||||
if (date_to and date_from) and (date_from <= date_to):
|
||||
diff_day = self._get_number_of_days(date_from, date_to)
|
||||
result['value'] = {
|
||||
'number_of_days_temp': round(math.floor(diff_day))+1
|
||||
}
|
||||
return result
|
||||
result['value'] = {
|
||||
'number_of_days_temp': 0,
|
||||
}
|
||||
result['value']['number_of_days_temp'] = round(math.floor(diff_day))+1
|
||||
else:
|
||||
result['value']['number_of_days_temp'] = 0
|
||||
|
||||
return result
|
||||
|
||||
def onchange_date_to(self, cr, uid, ids, date_to, date_from):
|
||||
"""
|
||||
Update the number_of_days.
|
||||
"""
|
||||
|
||||
# date_to has to be greater than date_from
|
||||
if (date_from and date_to) and (date_from > date_to):
|
||||
raise osv.except_osv(_('Warning!'),_('The start date must be anterior to the end date.'))
|
||||
|
||||
result = {'value': {}}
|
||||
|
||||
# Compute and update the number of days
|
||||
if (date_to and date_from) and (date_from <= date_to):
|
||||
diff_day = self._get_number_of_days(date_from, date_to)
|
||||
result['value']['number_of_days_temp'] = round(math.floor(diff_day))+1
|
||||
else:
|
||||
result['value']['number_of_days_temp'] = 0
|
||||
|
||||
return result
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
check_fnct = self.pool.get('hr.holidays.status').check_access_rights
|
||||
for holiday in self.browse(cr, uid, ids, context=context):
|
||||
if holiday.state in ('validate','validate1') and not check_fnct(cr, uid, 'write', raise_exception=False):
|
||||
raise osv.except_osv(_('Warning!'),_('You cannot modify a leave request that has been approved. Contact a human resource manager.'))
|
||||
return super(hr_holidays, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def set_to_draft(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {
|
||||
'state': 'draft',
|
||||
|
@ -430,10 +489,10 @@ class hr_employee(osv.osv):
|
|||
def _get_remaining_days(self, cr, uid, ids, name, args, context=None):
|
||||
cr.execute("""SELECT
|
||||
sum(h.number_of_days) as days,
|
||||
h.employee_id
|
||||
h.employee_id
|
||||
from
|
||||
hr_holidays h
|
||||
join hr_holidays_status s on (s.id=h.holiday_status_id)
|
||||
join hr_holidays_status s on (s.id=h.holiday_status_id)
|
||||
where
|
||||
h.state='validate' and
|
||||
s.limit=False and
|
||||
|
@ -448,9 +507,9 @@ class hr_employee(osv.osv):
|
|||
remaining[employee_id] = 0.0
|
||||
return remaining
|
||||
|
||||
def _get_leave_status(self, cr, uid, ids, name, args, context=None):
|
||||
def _get_leave_status(self, cr, uid, ids, name, args, context=None):
|
||||
holidays_obj = self.pool.get('hr.holidays')
|
||||
holidays_id = holidays_obj.search(cr, uid,
|
||||
holidays_id = holidays_obj.search(cr, uid,
|
||||
[('employee_id', 'in', ids), ('date_from','<=',time.strftime('%Y-%m-%d %H:%M:%S')),
|
||||
('date_to','>=',time.strftime('%Y-%m-%d 23:59:59')),('type','=','remove'),('state','not in',('cancel','refuse'))],
|
||||
context=context)
|
||||
|
@ -476,7 +535,7 @@ class hr_employee(osv.osv):
|
|||
('validate1', 'Waiting Second Approval'), ('validate', 'Approved'), ('cancel', 'Cancelled')]),
|
||||
'current_leave_id': fields.function(_get_leave_status, multi="leave_status", string="Current Leave Type",type='many2one', relation='hr.holidays.status'),
|
||||
'leave_date_from': fields.function(_get_leave_status, multi='leave_status', type='date', string='From Date'),
|
||||
'leave_date_to': fields.function(_get_leave_status, multi='leave_status', type='date', string='To Date'),
|
||||
'leave_date_to': fields.function(_get_leave_status, multi='leave_status', type='date', string='To Date'),
|
||||
}
|
||||
|
||||
hr_employee()
|
||||
|
|
|
@ -34,8 +34,8 @@
|
|||
<record model="hr.holidays" id="hr_holidays_employee1_vc">
|
||||
<field name="name">Summer Vacation</field>
|
||||
<field name="holiday_status_id" ref="holiday_status_unpaid"/>
|
||||
<field eval="time.strftime('%Y-%m-20')" name="date_from"/>
|
||||
<field eval="time.strftime('%Y-%m-22')" name="date_to"/>
|
||||
<field eval="time.strftime('%Y-%m-23')" name="date_from"/>
|
||||
<field eval="time.strftime('%Y-%m-25')" name="date_to"/>
|
||||
<field name="type">add</field>
|
||||
<field name="state">draft</field>
|
||||
<field name="number_of_days_temp">7</field>
|
||||
|
@ -45,8 +45,8 @@
|
|||
<record model="hr.holidays" id="hr_holidays_employee1_int_tour">
|
||||
<field name="name">International Tour</field>
|
||||
<field name="holiday_status_id" ref="holiday_status_comp"/>
|
||||
<field eval="time.strftime('%Y-%m-20')" name="date_from"/>
|
||||
<field eval="time.strftime('%Y-%m-22')" name="date_to"/>
|
||||
<field eval="time.strftime('%Y-%m-26')" name="date_from"/>
|
||||
<field eval="time.strftime('%Y-%m-28')" name="date_to"/>
|
||||
<field name="type">add</field>
|
||||
<field name="number_of_days_temp">7</field>
|
||||
<field name="employee_id" ref="hr.employee_fp"/>
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
<record id="action_holidays_unread" model="ir.values">
|
||||
<field name="name">action_holidays_unread</field>
|
||||
<field name="action_id" ref="actions_server_holidays_unread"/>
|
||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_holidays_unread'))" />
|
||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_holidays_unread'))"/>
|
||||
<field name="key">action</field>
|
||||
<field name="model_id" ref="model_hr_holidays" />
|
||||
<field name="model_id" ref="model_hr_holidays"/>
|
||||
<field name="model">hr.holidays</field>
|
||||
<field name="key2">client_action_multi</field>
|
||||
</record>
|
||||
|
@ -31,9 +31,9 @@
|
|||
<record id="action_holidays_read" model="ir.values">
|
||||
<field name="name">action_holidays_read</field>
|
||||
<field name="action_id" ref="actions_server_holidays_read"/>
|
||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_holidays_read'))" />
|
||||
<field name="value" eval="'ir.actions.server,' + str(ref('actions_server_holidays_read'))"/>
|
||||
<field name="key">action</field>
|
||||
<field name="model_id" ref="model_hr_holidays" />
|
||||
<field name="model_id" ref="model_hr_holidays"/>
|
||||
<field name="model">hr.holidays</field>
|
||||
<field name="key2">client_action_multi</field>
|
||||
</record>
|
||||
|
@ -83,7 +83,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="edit_holiday_new">
|
||||
<record id="edit_holiday_new" model="ir.ui.view">
|
||||
<field name="name">Leave Request</field>
|
||||
<field name="model">hr.holidays</field>
|
||||
<field name="priority">1</field>
|
||||
|
@ -93,7 +93,7 @@
|
|||
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
|
||||
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
|
||||
<button string="Refuse" name="refuse" states="confirm,validate1,validate" type="workflow" groups="base.group_hr_user"/>
|
||||
<button string="Reset to New" name="set_to_draft" states="refuse" type="object" groups="base.group_hr_user" />
|
||||
<button string="Reset to New" name="set_to_draft" states="refuse" type="object" groups="base.group_hr_user"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
|
||||
</header>
|
||||
<sheet string="Leave Request">
|
||||
|
@ -101,11 +101,11 @@
|
|||
<group>
|
||||
<field name="name" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
||||
<field name="holiday_status_id" context="{'employee_id':employee_id}"/>
|
||||
<label for="number_of_days_temp" string="Duration"/>
|
||||
<label for="number_of_days_temp" string="Duration" help="The default duration interval between the start date and the end date is 8 hours. Feel free to adapt it to your needs."/>
|
||||
<div>
|
||||
<group col="3">
|
||||
<field name="date_from" nolabel="1" on_change="onchange_date_from(date_to, date_from)" required="1" class="oe_inline"/><label string="-" class="oe_inline" />
|
||||
<field name="date_to" nolabel="1" on_change="onchange_date_from(date_to, date_from)" required="1" class="oe_inline"/>
|
||||
<field name="date_from" nolabel="1" on_change="onchange_date_from(date_to, date_from)" required="1" class="oe_inline"/><label string="-" class="oe_inline"/>
|
||||
<field name="date_to" nolabel="1" on_change="onchange_date_to(date_to, date_from)" required="1" class="oe_inline"/>
|
||||
</group>
|
||||
<div>
|
||||
<field name="number_of_days_temp" class="oe_inline"/> days
|
||||
|
@ -115,7 +115,7 @@
|
|||
</group>
|
||||
<group>
|
||||
<field name="holiday_type" on_change="onchange_type(holiday_type)" attrs="{'readonly':[('state','!=','draft')]}" width="130" string="Mode" groups="base.group_hr_user"/>
|
||||
<field name="employee_id" attrs="{'required':[('holiday_type','=','employee')],'invisible':[('holiday_type','=','category')]}" groups="base.group_hr_user"/>
|
||||
<field name="employee_id" attrs="{'required':[('holiday_type','=','employee')],'invisible':[('holiday_type','=','category')]}" on_change="onchange_employee(employee_id)" groups="base.group_hr_user"/>
|
||||
<field name="department_id" attrs="{'readonly':[('holiday_type','=','category')]}" groups="base.group_hr_user"/>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -138,7 +138,7 @@
|
|||
<button string="Approve" name="validate" states="confirm" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
|
||||
<button string="Validate" name="second_validate" states="validate1" type="workflow" groups="base.group_hr_user" class="oe_highlight"/>
|
||||
<button string="Refuse" name="refuse" states="confirm,validate,validate1" type="workflow" groups="base.group_hr_user"/>
|
||||
<button string="Reset to New" name="set_to_draft" states="cancel,refuse" type="object" groups="base.group_hr_user" />
|
||||
<button string="Reset to New" name="set_to_draft" states="cancel,refuse" type="object" groups="base.group_hr_user"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate" statusbar_colors='{"confirm":"blue","validate1":"blue","refuse":"red"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
|
@ -233,7 +233,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_holiday">
|
||||
<field name="name">hr.holidays.tree</field>
|
||||
<field name="model">hr.holidays</field>
|
||||
|
@ -251,7 +250,6 @@
|
|||
<field name="holiday_status_id" invisible="1"/>
|
||||
<field name="manager_id" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<!--field name="type"/-->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -268,7 +266,7 @@
|
|||
<field name="search_view_id" ref="view_hr_holidays_filter"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new leave request.
|
||||
Click to create a new leave request.
|
||||
</p><p>
|
||||
Once you have recorded your leave request, it will be sent
|
||||
to a manager for validation. Be sure to set the right leave
|
||||
|
@ -298,7 +296,7 @@
|
|||
<field name="view_id" ref="view_holiday_new_calendar"/>
|
||||
<field name="act_window_id" ref="open_ask_holidays"/>
|
||||
</record>
|
||||
|
||||
|
||||
<menuitem name="My Leave Requests" parent="menu_open_ask_holidays" id="menu_open_ask_holidays_new" action="open_ask_holidays"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="request_approve_holidays">
|
||||
|
@ -392,7 +390,7 @@
|
|||
|
||||
<menuitem name="Leaves Summary" parent="menu_open_ask_holidays" id="menu_open_company_allocation" action="open_company_allocation" sequence="40"/>
|
||||
|
||||
<!-- holidays status -->
|
||||
<!-- Holidays status -->
|
||||
<record id="view_holidays_status_filter" model="ir.ui.view">
|
||||
<field name="name">hr.holidays.status.filter</field>
|
||||
<field name="model">hr.holidays.status</field>
|
||||
|
@ -443,6 +441,7 @@
|
|||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_holiday_status_normal_tree">
|
||||
<field name="name">hr.holidays.status.normal.tree</field>
|
||||
<field name="model">hr.holidays.status</field>
|
||||
|
@ -467,7 +466,7 @@
|
|||
</record>
|
||||
|
||||
<record id="open_view_holiday_status" model="ir.actions.act_window">
|
||||
<field name="name">Leave Type</field>
|
||||
<field name="name">Leave Types</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">hr.holidays.status</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -477,9 +476,9 @@
|
|||
</record>
|
||||
|
||||
<menuitem sequence="3" id="hr.menu_open_view_attendance_reason_config" parent="hr.menu_hr_configuration" name="Leaves"/>
|
||||
<menuitem name="Leave Type" action="open_view_holiday_status" id="menu_open_view_holiday_status" parent="hr.menu_hr_configuration" sequence="10" />
|
||||
<menuitem name="Leave Type" action="open_view_holiday_status" id="menu_open_view_holiday_status" parent="hr.menu_hr_configuration" sequence="10"/>
|
||||
|
||||
<!-- holiday on resource leave -->
|
||||
<!-- Holiday on resource leave -->
|
||||
<record id="resource_calendar_leave_form_inherit" model="ir.ui.view">
|
||||
<field name="name">resource.calendar.leaves.form.inherit</field>
|
||||
<field name="model">resource.calendar.leaves</field>
|
||||
|
@ -491,7 +490,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
<!-- Shortcuts -->
|
||||
<record id="act_hr_employee_holiday_request" model="ir.actions.act_window">
|
||||
<field name="name">Leaves</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -504,8 +503,7 @@
|
|||
<field name="view_id" eval="view_holiday"/>
|
||||
</record>
|
||||
|
||||
<!-- Assing leave -->
|
||||
|
||||
<!-- Assing leave -->
|
||||
<record id="hr_holidays_leaves_assign_tree_view" model="ir.ui.view">
|
||||
<field name="name">hr.employee.leave.tree</field>
|
||||
<field name="model">hr.employee</field>
|
||||
|
@ -534,7 +532,6 @@
|
|||
</record>
|
||||
|
||||
<!-- Hr employee inherit Legal Leaves -->
|
||||
|
||||
<record id="view_employee_form_leave_inherit" model="ir.ui.view">
|
||||
<field name="name">hr.employee.leave.form.inherit</field>
|
||||
<field name="model">hr.employee</field>
|
||||
|
|
|
@ -312,12 +312,7 @@ class hr_payslip(osv.osv):
|
|||
company_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
|
||||
default.update({
|
||||
'line_ids': [],
|
||||
'move_ids': [],
|
||||
'move_line_ids': [],
|
||||
'company_id': company_id,
|
||||
'period_id': False,
|
||||
'basic_before_leaves': 0.0,
|
||||
'basic_amount': 0.0,
|
||||
'number': '',
|
||||
'payslip_run_id': False,
|
||||
'paid': False,
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
'name': 'Recruitment Process',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 24,
|
||||
'sequence': 25,
|
||||
'summary': 'Jobs, Recruitment, Applications, Job Interviews',
|
||||
'description': """
|
||||
Manage job positions and the recruitment process
|
||||
|
|
|
@ -258,6 +258,17 @@ class hr_applicant(base_stage, osv.Model):
|
|||
stage_id = stage_ids and stage_ids[0] or False
|
||||
return {'value': {'stage_id': stage_id}}
|
||||
|
||||
def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
|
||||
data = {'partner_phone': False,
|
||||
'partner_mobile': False,
|
||||
'email_from': False}
|
||||
if partner_id:
|
||||
addr = self.pool.get('res.partner').browse(cr, uid, partner_id, context)
|
||||
data.update({'partner_phone': addr.phone,
|
||||
'partner_mobile': addr.mobile,
|
||||
'email_from': addr.email})
|
||||
return {'value': data}
|
||||
|
||||
def stage_find(self, cr, uid, cases, section_id, domain=[], order='sequence', context=None):
|
||||
""" Override of the base.stage method
|
||||
Parameter of the stage search taken from the lead:
|
||||
|
|
|
@ -135,7 +135,7 @@
|
|||
<group>
|
||||
<group>
|
||||
<field name="partner_id"
|
||||
on_change="onchange_partner_id(partner_id, email_from)"/>
|
||||
on_change="onchange_partner_id(partner_id)"/>
|
||||
<field name="email_from" widget="email"/>
|
||||
<field name="partner_phone"/>
|
||||
<field name="partner_mobile"/>
|
||||
|
|
|
@ -16,7 +16,7 @@ openerp.hr_recruitment = function(openerp) {
|
|||
|
||||
// Find their matching names
|
||||
var dataset = new openerp.web.DataSetSearch(self, 'hr.applicant_category', self.session.context, [['id', 'in', _.uniq(categ_ids)]]);
|
||||
dataset.read_slice(['id', 'name']).then(function(result) {
|
||||
dataset.read_slice(['id', 'name']).done(function(result) {
|
||||
_.each(result, function(v, k) {
|
||||
// Set the proper value in the DOM and display the element
|
||||
self.$el.find('span[data-categ_id=' + v.id + ']').text(v.name);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
applicant_ids = self.search(cr, uid, [('email_from','=', 'Mr. Richard Anderson <Richard_Anderson@yahoo.com>')])
|
||||
assert applicant_ids, "Applicant is not created after getting the mail"
|
||||
applicant = self.browse(cr, uid, applicant_ids[0], context=context)
|
||||
resume_ids = self.pool.get('ir.attachment').search(cr, uid, [('datas_fname','=','resume.doc'),('res_model','=',self._name),('res_id','=',applicant.id)])
|
||||
resume_ids = self.pool.get('ir.attachment').search(cr, uid, [('datas_fname','=','resume.pdf'),('res_model','=',self._name),('res_id','=',applicant.id)])
|
||||
assert applicant.name == "Application for the post of Jr.application Programmer.", "Applicant name does not match."
|
||||
assert applicant.stage_id.id == ref('hr_recruitment.stage_job1'), "Stage should be 'Initial qualification' and is '%s'." % (applicant.stage_id.name)
|
||||
assert applicant.state == "draft", "Applicant state should be 'draft'."
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,7 @@
|
|||
'name': 'Timesheets',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 23,
|
||||
'description': """
|
||||
This module implements a timesheet system.
|
||||
==========================================
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<field name="factor">50.0</field>
|
||||
</record>
|
||||
<record id="timesheet_invoice_factor3" model="hr_timesheet_invoice.factor">
|
||||
<field name="name">Gratis</field>
|
||||
<field name="name">Free of charge</field>
|
||||
<field name="customer_name">Offered developments</field>
|
||||
<field name="factor">100.0</field>
|
||||
</record>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
'name': 'Timesheets',
|
||||
'version': '1.0',
|
||||
'category': 'Human Resources',
|
||||
'sequence': 16,
|
||||
'sequence': 24,
|
||||
'summary': 'Timesheets, Attendances, Activities',
|
||||
'description': """
|
||||
Record and validate timesheets and attendances easily
|
||||
|
|
|
@ -46,7 +46,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
var commands = this.field_manager.get_field_value("timesheet_ids");
|
||||
this.res_o2m_drop.add(new instance.web.Model(this.view.model).call("resolve_2many_commands", ["timesheet_ids", commands, [],
|
||||
new instance.web.CompoundContext()]))
|
||||
.then(function(result) {
|
||||
.done(function(result) {
|
||||
self.querying = true;
|
||||
self.set({sheets: result});
|
||||
self.querying = false;
|
||||
|
@ -57,7 +57,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
if (self.querying)
|
||||
return;
|
||||
self.updating = true;
|
||||
self.field_manager.set_values({timesheet_ids: self.get("sheets")}).then(function() {
|
||||
self.field_manager.set_values({timesheet_ids: self.get("sheets")}).done(function() {
|
||||
self.updating = false;
|
||||
});
|
||||
},
|
||||
|
@ -85,7 +85,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
var default_get;
|
||||
return this.render_drop.add(new instance.web.Model("hr.analytic.timesheet").call("default_get", [
|
||||
['account_id','general_account_id', 'journal_id','date','name','user_id','product_id','product_uom_id','to_invoice','amount','unit_amount'],
|
||||
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).pipe(function(result) {
|
||||
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(result) {
|
||||
default_get = result;
|
||||
// calculating dates
|
||||
dates = [];
|
||||
|
@ -108,9 +108,9 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
var account_ids = _.map(_.keys(accounts), function(el) { return el === "false" ? false : Number(el) });
|
||||
|
||||
return new instance.web.Model("hr.analytic.timesheet").call("multi_on_change_account_id", [[], account_ids,
|
||||
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).pipe(function(accounts_defaults) {
|
||||
new instance.web.CompoundContext({'user_id': self.get('user_id')})]).then(function(accounts_defaults) {
|
||||
accounts = _(accounts).chain().map(function(lines, account_id) {
|
||||
account_defaults = _.extend({}, default_get, accounts_defaults[account_id]);
|
||||
account_defaults = _.extend({}, default_get, (accounts_defaults[account_id] || {}).value || {});
|
||||
// group by days
|
||||
account_id = account_id === "false" ? false : Number(account_id);
|
||||
var index = _.groupBy(lines, "date");
|
||||
|
@ -136,7 +136,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
|
||||
// we need the name_get of the analytic accounts
|
||||
return new instance.web.Model("account.analytic.account").call("name_get", [_.pluck(accounts, "account"),
|
||||
new instance.web.CompoundContext()]).pipe(function(result) {
|
||||
new instance.web.CompoundContext()]).then(function(result) {
|
||||
account_names = {};
|
||||
_.each(result, function(el) {
|
||||
account_names[el[0]] = el[1];
|
||||
|
@ -146,7 +146,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
});
|
||||
});;
|
||||
});
|
||||
})).pipe(function(result) {
|
||||
})).then(function(result) {
|
||||
// we put all the gathered data in self, then we render
|
||||
self.dates = dates;
|
||||
self.accounts = accounts;
|
||||
|
@ -222,7 +222,7 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
return;
|
||||
}
|
||||
var ops = self.generate_o2m_value();
|
||||
new instance.web.Model("hr.analytic.timesheet").call("on_change_account_id", [[], id]).pipe(function(res) {
|
||||
new instance.web.Model("hr.analytic.timesheet").call("on_change_account_id", [[], id]).then(function(res) {
|
||||
var def = _.extend({}, self.default_get, res.value, {
|
||||
name: self.description_line,
|
||||
unit_amount: 0,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
# Spanish translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 00:36+0000\n"
|
||||
"PO-Revision-Date: 2012-11-08 16:01+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-09 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16250)\n"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid ""
|
||||
"\n"
|
||||
"Please define BIC/Swift code on bank for bank type IBAN Account to make "
|
||||
"valid payments"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Por favor defina el código BIC/Swift del banco para una cuenta de tipo IBAN "
|
||||
"para realizar pagos válidos"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type,name:l10n_fr_rib.bank_rib
|
||||
msgid "RIB and optional IBAN"
|
||||
msgstr "CC e IBAN opcional"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,rib_acc_number:0
|
||||
msgid "RIB account number"
|
||||
msgstr "Número de la cuenta"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,bank_code:0
|
||||
msgid "Bank Code"
|
||||
msgstr "Código de banco"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:54
|
||||
#, python-format
|
||||
msgid "The RIB key %s does not correspond to the other codes: %s %s %s."
|
||||
msgstr "La clave de la CC %s no se corresponde con otros códigos: %s %s %s."
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_office_field
|
||||
msgid "office"
|
||||
msgstr "oficina"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.bank,rib_code:0
|
||||
msgid "RIB Bank Code"
|
||||
msgstr "Código CC"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:58
|
||||
#, python-format
|
||||
msgid "The IBAN %s is not valid."
|
||||
msgstr "El IBAN %s no es válido."
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:ir.model,name:l10n_fr_rib.model_res_partner_bank
|
||||
msgid "Bank Accounts"
|
||||
msgstr "Cuentas bancarias"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,office:0
|
||||
msgid "Office Code"
|
||||
msgstr "Código de oficina"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bic_field
|
||||
msgid "bank_bic"
|
||||
msgstr "Número BIC"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_bank_code_field
|
||||
msgid "bank_code"
|
||||
msgstr "código bancario"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_key_field
|
||||
msgid "key"
|
||||
msgstr "clave"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_rib_acc_number_field
|
||||
msgid "rib_acc_number"
|
||||
msgstr "Número CC"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: help:res.partner.bank,key:0
|
||||
msgid ""
|
||||
"The key is a number allowing to check the correctness of the other codes."
|
||||
msgstr ""
|
||||
"La clave es un número que permite comprobar si el resto de códigos son "
|
||||
"correctos."
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: field:res.partner.bank,key:0
|
||||
msgid "Key"
|
||||
msgstr "Clave"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: code:addons/l10n_fr_rib/bank.py:53
|
||||
#: code:addons/l10n_fr_rib/bank.py:58
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type,format_layout:l10n_fr_rib.bank_rib
|
||||
msgid "%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s"
|
||||
msgstr "%(bank_name)s: %(bank_code)s %(office)s %(rib_acc_number)s %(key)s"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: constraint:res.partner.bank:0
|
||||
msgid "The RIB and/or IBAN is not valid"
|
||||
msgstr "La CC y/o IBAN no es válida"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:ir.model,name:l10n_fr_rib.model_res_bank
|
||||
msgid "Bank"
|
||||
msgstr "Banco"
|
||||
|
||||
#. module: l10n_fr_rib
|
||||
#: model:res.partner.bank.type.field,name:l10n_fr_rib.rib_acc_number_field
|
||||
msgid "acc_number"
|
||||
msgstr "Número cuenta"
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
# Spanish translation for openobject-addons
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-02-08 01:06+0000\n"
|
||||
"PO-Revision-Date: 2012-11-08 14:29+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-11-09 04:39+0000\n"
|
||||
"X-Generator: Launchpad (build 16250)\n"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position_template
|
||||
msgid "Template for Fiscal Position"
|
||||
msgstr "Plantilla para posición fiscal"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.account:0
|
||||
msgid "The code of the account must be unique per company !"
|
||||
msgstr "¡El código de la cuenta debe ser único por compañía!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account.template:0
|
||||
msgid ""
|
||||
"Configuration Error!\n"
|
||||
"You can not define children to an account with internal type different of "
|
||||
"\"View\"! "
|
||||
msgstr ""
|
||||
"Error de configuración!\n"
|
||||
"¡No puede definir hijos para una cuenta con el tipo interno distinto de "
|
||||
"\"Vista\"! "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_analytic_journal
|
||||
msgid "Analytic Journal"
|
||||
msgstr "Diario analítico"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account.template:0
|
||||
msgid "Error ! You can not create recursive account templates."
|
||||
msgstr "¡Error! No puede crear plantillas de cuentas recursivas."
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_journal
|
||||
msgid "Journal"
|
||||
msgstr "Diario"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_chart_template
|
||||
msgid "Templates for Account Chart"
|
||||
msgstr "Plantillas para el plan contable"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.tax:0
|
||||
msgid "The description must be unique per company!"
|
||||
msgstr "¡La descripción debe ser única por compañia!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.tax.code.template:0
|
||||
msgid "Error ! You can not create recursive Tax Codes."
|
||||
msgstr "¡Error! No puede crear códigos de impuestos recursivos."
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax_template
|
||||
msgid "account.tax.template"
|
||||
msgstr "Plantilla de impuestos"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax
|
||||
msgid "account.tax"
|
||||
msgstr "Impuesto"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_account
|
||||
msgid "Account"
|
||||
msgstr "Cuenta"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_wizard_multi_charts_accounts
|
||||
msgid "wizard.multi.charts.accounts"
|
||||
msgstr "Asistente de plan de cuentas"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.journal:0
|
||||
msgid ""
|
||||
"Configuration error! The currency chosen should be shared by the default "
|
||||
"accounts too."
|
||||
msgstr ""
|
||||
"¡Error de configuración! La moneda elegida debería ser también la misma en "
|
||||
"las cuentas por defecto"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_account_template
|
||||
msgid "Templates for Accounts"
|
||||
msgstr "Plantillas para cuentas"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: help:account.chart.template,spoken_languages:0
|
||||
msgid ""
|
||||
"State here the languages for which the translations of templates could be "
|
||||
"loaded at the time of installation of this localization module and copied in "
|
||||
"the final object when generating them from templates. You must provide the "
|
||||
"language codes separated by ';'"
|
||||
msgstr ""
|
||||
"Indique aquí los idiomas para los que las traducciones de las plantillas "
|
||||
"pueden ser cargadas en el momento de la instalación de este módulo de "
|
||||
"localización y copiados en el objeto final cuando se generen desde las "
|
||||
"plantillas. Debe proveer los códigos de idioma separados por ';'."
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid "Error ! You can not create recursive accounts."
|
||||
msgstr "¡Error! No se pueden crear cuentas recursivas."
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid ""
|
||||
"Configuration Error! \n"
|
||||
"You can not select an account type with a deferral method different of "
|
||||
"\"Unreconciled\" for accounts with internal type \"Payable/Receivable\"! "
|
||||
msgstr ""
|
||||
"¡Error de configuración! \n"
|
||||
"¡No puede seleccionar un tipo de cuenta con un método de cierre diferente de "
|
||||
"\"Reconciliado\" para las cuentas con tipo interno \"A pagar/A cobrar\"! "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The name of the journal must be unique per company !"
|
||||
msgstr "¡El nombre del diaro debe ser único por compañía!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_analytic_account
|
||||
msgid "Analytic Account"
|
||||
msgstr "Cuenta analítica"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: sql_constraint:account.journal:0
|
||||
msgid "The code of the journal must be unique per company !"
|
||||
msgstr "¡El código del diario debe ser único por compañía!"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_fiscal_position
|
||||
msgid "Fiscal Position"
|
||||
msgstr "Posición fiscal"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.account:0
|
||||
msgid ""
|
||||
"Configuration Error! \n"
|
||||
"You can not define children to an account with internal type different of "
|
||||
"\"View\"! "
|
||||
msgstr ""
|
||||
"¡Error de configuración! \n"
|
||||
"¡No puede definir hijos en una cuenta con tipo interno distinto a \"Vista\"! "
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: constraint:account.analytic.account:0
|
||||
msgid "Error! You can not create recursive analytic accounts."
|
||||
msgstr "¡Error! No puede crear cuentas analíticas recursivas."
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: model:ir.model,name:l10n_multilang.model_account_tax_code_template
|
||||
msgid "Tax Code Template"
|
||||
msgstr "Plantilla códigos de impuestos"
|
||||
|
||||
#. module: l10n_multilang
|
||||
#: field:account.chart.template,spoken_languages:0
|
||||
msgid "Spoken Languages"
|
||||
msgstr "Idiomas hablados"
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -641,11 +641,12 @@
|
|||
<field name="account_paid_id" ref="a_wht_income"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
<!-- INSTALL ACTION -->
|
||||
<data noupdate="1">
|
||||
<!-- INSTALL ACTION -->
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp><!-- vim: set fdm=marker : -->
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<data noupdate="1">
|
||||
<record id="account.action_wizard_multi_chart_todo" model="ir.actions.todo">
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -20,7 +20,5 @@
|
|||
##############################################################################
|
||||
|
||||
import lunch
|
||||
import wizard
|
||||
import report
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
import wizard
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2004-2012 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -22,31 +22,31 @@
|
|||
{
|
||||
'name': 'Lunch Orders',
|
||||
'author': 'OpenERP SA',
|
||||
'version': '0.1',
|
||||
'depends': [],
|
||||
'version': '0.2',
|
||||
'depends': ['base'],
|
||||
'category' : 'Tools',
|
||||
'summary': 'Lunch Order, Meal, Food',
|
||||
'description': """
|
||||
The base module to manage lunch.
|
||||
================================
|
||||
|
||||
keep track for the Lunch Order, Cash Moves, CashBox, Product. Apply Different
|
||||
Category for the product.
|
||||
""",
|
||||
'data': [
|
||||
'security/lunch_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/lunch_order_cancel_view.xml',
|
||||
'wizard/lunch_order_confirm_view.xml',
|
||||
'wizard/lunch_cashbox_clean_view.xml',
|
||||
'lunch_view.xml',
|
||||
'lunch_report.xml',
|
||||
'report/report_lunch_order_view.xml',
|
||||
'lunch_installer_view.xml'
|
||||
],
|
||||
'demo': ['lunch_demo.xml'],
|
||||
'test': ['test/test_lunch.yml', 'test/lunch_report.yml'],
|
||||
'installable': True,
|
||||
'images': ['images/cash_moves.jpeg','images/lunch_orders.jpeg','images/products.jpeg'],
|
||||
}
|
||||
Many companies order sandwiches, pizzas and other, from usual suppliers, for their employees to offer them more facilities.
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
However lunches management within the company requires proper administration especially when the number of employees or suppliers is important.
|
||||
|
||||
The “Lunch Order” module has been developed to make this management easier but also to offer employees more tools and usability.
|
||||
|
||||
In addition to a full meal and supplier management, this module offers the possibility to display warning and provides quick order selection based on employee’s preferences.
|
||||
|
||||
If you want to save your employees' time and avoid them to always have coins in their pockets, this module is essential.
|
||||
""",
|
||||
'data': ['security/lunch_security.xml','lunch_view.xml','wizard/lunch_order_view.xml','wizard/lunch_validation_view.xml','wizard/lunch_cancel_view.xml','lunch_report.xml',
|
||||
'report/report_lunch_order_view.xml',
|
||||
'security/ir.model.access.csv',],
|
||||
'css':['static/src/css/lunch.css'],
|
||||
'demo': ['lunch_demo.xml',],
|
||||
'installable': True,
|
||||
'application' : True,
|
||||
'certificate' : '001292377792581874189',
|
||||
'images': [],
|
||||
}
|
||||
|
|
|
@ -19,234 +19,451 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from xml.sax.saxutils import escape
|
||||
import time
|
||||
from osv import osv, fields
|
||||
from datetime import datetime
|
||||
from lxml import etree
|
||||
import tools
|
||||
from tools.translate import _
|
||||
|
||||
class lunch_category(osv.osv):
|
||||
""" Lunch category """
|
||||
|
||||
_name = 'lunch.category'
|
||||
_description = "Category"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True, size=50),
|
||||
}
|
||||
_order = 'name'
|
||||
|
||||
lunch_category()
|
||||
|
||||
|
||||
class lunch_product(osv.osv):
|
||||
""" Lunch Product """
|
||||
|
||||
_name = 'lunch.product'
|
||||
_description = "Lunch Product"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=50, required=True),
|
||||
'category_id': fields.many2one('lunch.category', 'Category'),
|
||||
'description': fields.text('Description', size=128, required=False),
|
||||
'price': fields.float('Price', digits=(16,2)),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a : True,
|
||||
}
|
||||
|
||||
lunch_product()
|
||||
|
||||
|
||||
class lunch_cashbox(osv.osv):
|
||||
""" cashbox for Lunch """
|
||||
|
||||
_name = 'lunch.cashbox'
|
||||
_description = "Cashbox for Lunch "
|
||||
|
||||
|
||||
def amount_available(self, cr, uid, ids, field_name, arg, context=None):
|
||||
|
||||
""" count available amount
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of create menu’s IDs
|
||||
@param context: A standard dictionary for contextual values """
|
||||
|
||||
cr.execute("SELECT box,sum(amount) from lunch_cashmove where active = 't' group by box")
|
||||
amount = dict(cr.fetchall())
|
||||
for i in ids:
|
||||
amount.setdefault(i, 0)
|
||||
return amount
|
||||
|
||||
_columns = {
|
||||
'manager': fields.many2one('res.users', 'Manager'),
|
||||
'name': fields.char('Name', size=30, required=True, unique = True),
|
||||
'sum_remain': fields.function(amount_available, string='Total Remaining'),
|
||||
}
|
||||
|
||||
lunch_cashbox()
|
||||
|
||||
|
||||
class lunch_cashmove(osv.osv):
|
||||
""" Move cash """
|
||||
|
||||
_name = 'lunch.cashmove'
|
||||
_description = "Cash Move"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=128),
|
||||
'user_cashmove': fields.many2one('res.users', 'User Name', required=True),
|
||||
'amount': fields.float('Amount', digits=(16, 2)),
|
||||
'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
'create_date': fields.datetime('Creation Date', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: True,
|
||||
}
|
||||
|
||||
lunch_cashmove()
|
||||
|
||||
|
||||
class lunch_order(osv.osv):
|
||||
""" Apply lunch order """
|
||||
|
||||
class lunch_order(osv.Model):
|
||||
"""
|
||||
lunch order (contains one or more lunch order line(s))
|
||||
"""
|
||||
_name = 'lunch.order'
|
||||
_description = "Lunch Order"
|
||||
_rec_name = "user_id"
|
||||
_description = 'Lunch Order'
|
||||
|
||||
def _price_get(self, cr, uid, ids, name, args, context=None):
|
||||
def _price_get(self, cr, uid, ids, name, arg, context=None):
|
||||
"""
|
||||
get and sum the order lines' price
|
||||
"""
|
||||
result = dict.fromkeys(ids, 0)
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
result[order.id] = sum(order_line.product_id.price
|
||||
for order_line in order.order_line_ids)
|
||||
return result
|
||||
|
||||
""" Get Price of Product
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Lunch order’s IDs
|
||||
@param context: A standard dictionary for contextual values """
|
||||
def _fetch_orders_from_lines(self, cr, uid, ids, name, context=None):
|
||||
"""
|
||||
return the list of lunch orders to which belong the order lines `ids´
|
||||
"""
|
||||
result = set()
|
||||
for order_line in self.browse(cr, uid, ids, context=context):
|
||||
if order_line.order_id:
|
||||
result.add(order_line.order_id.id)
|
||||
return list(result)
|
||||
|
||||
res = {}
|
||||
for price in self.browse(cr, uid, ids, context=context):
|
||||
res[price.id] = price.product.price
|
||||
def add_preference(self, cr, uid, ids, pref_id, context=None):
|
||||
"""
|
||||
create a new order line based on the preference selected (pref_id)
|
||||
"""
|
||||
assert len(ids) == 1
|
||||
orderline_ref = self.pool.get('lunch.order.line')
|
||||
prod_ref = self.pool.get('lunch.product')
|
||||
order = self.browse(cr, uid, ids[0], context=context)
|
||||
pref = orderline_ref.browse(cr, uid, pref_id, context=context)
|
||||
new_order_line = {
|
||||
'date': order.date,
|
||||
'user_id': uid,
|
||||
'product_id': pref.product_id.id,
|
||||
'note': pref.note,
|
||||
'order_id': order.id,
|
||||
'price': pref.product_id.price,
|
||||
'supplier': pref.product_id.supplier.id
|
||||
}
|
||||
return orderline_ref.create(cr, uid, new_order_line, context=context)
|
||||
|
||||
def _alerts_get(self, cr, uid, ids, name, arg, context=None):
|
||||
"""
|
||||
get the alerts to display on the order form
|
||||
"""
|
||||
result = {}
|
||||
alert_msg = self._default_alerts_get(cr, uid, context=context)
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
if order.state == 'new':
|
||||
result[order.id] = alert_msg
|
||||
return result
|
||||
|
||||
def check_day(self, alert):
|
||||
"""
|
||||
This method is used by can_display_alert
|
||||
to check if the alert day corresponds
|
||||
to the current day
|
||||
"""
|
||||
today = datetime.now().isoweekday()
|
||||
assert 1 <= today <= 7, "Should be between 1 and 7"
|
||||
mapping = dict((idx, name) for idx, name in enumerate('monday tuestday wednesday thursday friday saturday sunday'.split()))
|
||||
if today in mapping:
|
||||
return mapping[today]
|
||||
|
||||
def can_display_alert(self, alert):
|
||||
"""
|
||||
This method check if the alert can be displayed today
|
||||
"""
|
||||
if alert.alter_type == 'specific':
|
||||
#the alert is only activated on a specific day
|
||||
return alert.specific_day == time.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
|
||||
elif alert.alter_type == 'week':
|
||||
#the alert is activated during some days of the week
|
||||
return self.check_day(alert)
|
||||
|
||||
def _default_alerts_get(self, cr, uid, context=None):
|
||||
"""
|
||||
get the alerts to display on the order form
|
||||
"""
|
||||
alert_ref = self.pool.get('lunch.alert')
|
||||
alert_ids = alert_ref.search(cr, uid, [], context=context)
|
||||
alert_msg = []
|
||||
for alert in alert_ref.browse(cr, uid, alert_ids, context=context):
|
||||
#check if the address must be displayed today
|
||||
if self.can_display_alert(alert):
|
||||
#display the address only during its active time
|
||||
mynow = fields.datetime.context_timestamp(cr, uid, datetime.now(), context=context)
|
||||
hour_to = int(alert.active_to)
|
||||
min_to = int((alert.active_to - hour_to) * 60)
|
||||
to_alert = datetime.strptime(str(hour_to) + ":" + str(min_to), "%H:%M")
|
||||
hour_from = int(alert.active_from)
|
||||
min_from = int((alert.active_from - hour_from) * 60)
|
||||
from_alert = datetime.strptime(str(hour_from) + ":" + str(min_from), "%H:%M")
|
||||
if mynow.time() >= from_alert.time() and mynow.time() <= to_alert.time():
|
||||
alert_msg.append(alert.message)
|
||||
return '\n'.join(alert_msg)
|
||||
|
||||
def onchange_price(self, cr, uid, ids, order_line_ids, context=None):
|
||||
"""
|
||||
Onchange methode that refresh the total price of order
|
||||
"""
|
||||
res = {'value': {'total': 0.0}}
|
||||
order_line_ids = self.resolve_o2m_commands_to_record_dicts(cr, uid, "order_line_ids", order_line_ids, ["price"], context=context)
|
||||
if order_line_ids:
|
||||
tot = 0.0
|
||||
product_ref = self.pool.get("lunch.product")
|
||||
for prod in order_line_ids:
|
||||
if 'product_id' in prod:
|
||||
tot += product_ref.browse(cr, uid, prod['product_id'], context=context).price
|
||||
else:
|
||||
tot += prod['price']
|
||||
res = {'value': {'total': tot}}
|
||||
return res
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"""
|
||||
this method catch unexisting method call and if it starts with
|
||||
add_preference_'n' we execute the add_preference method with
|
||||
'n' as parameter
|
||||
"""
|
||||
if attr.startswith('add_preference_'):
|
||||
pref_id = int(attr[15:])
|
||||
def specific_function(cr, uid, ids, context=None):
|
||||
return self.add_preference(cr, uid, ids, pref_id, context=context)
|
||||
return specific_function
|
||||
return super(lunch_order,self).__getattr__(self,attr)
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type=False, context=None, toolbar=False, submenu=False):
|
||||
"""
|
||||
Add preferences in the form view of order.line
|
||||
"""
|
||||
res = super(lunch_order,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
|
||||
line_ref = self.pool.get("lunch.order.line")
|
||||
if view_type == 'form':
|
||||
doc = etree.XML(res['arch'])
|
||||
pref_ids = line_ref.search(cr, uid, [('user_id', '=', uid)], order='create_date desc', context=context)
|
||||
xml_start = etree.Element("div")
|
||||
#If there are no preference (it's the first time for the user)
|
||||
if len(pref_ids)==0:
|
||||
#create Elements
|
||||
xml_no_pref_1 = etree.Element("div")
|
||||
xml_no_pref_1.set('class','oe_inline oe_lunch_intro')
|
||||
xml_no_pref_2 = etree.Element("h3")
|
||||
xml_no_pref_2.text = _("This is the first time you order a meal")
|
||||
xml_no_pref_3 = etree.Element("p")
|
||||
xml_no_pref_3.set('class','oe_grey')
|
||||
xml_no_pref_3.text = _("Select a product and put your order comments on the note.")
|
||||
xml_no_pref_4 = etree.Element("p")
|
||||
xml_no_pref_4.set('class','oe_grey')
|
||||
xml_no_pref_4.text = _("Your favorite meals will be created based on your last orders.")
|
||||
xml_no_pref_5 = etree.Element("p")
|
||||
xml_no_pref_5.set('class','oe_grey')
|
||||
xml_no_pref_5.text = _("Don't forget the alerts displayed in the reddish area")
|
||||
#structure Elements
|
||||
xml_start.append(xml_no_pref_1)
|
||||
xml_no_pref_1.append(xml_no_pref_2)
|
||||
xml_no_pref_1.append(xml_no_pref_3)
|
||||
xml_no_pref_1.append(xml_no_pref_4)
|
||||
xml_no_pref_1.append(xml_no_pref_5)
|
||||
#Else: the user already have preferences so we display them
|
||||
else:
|
||||
preferences = line_ref.browse(cr, uid, pref_ids, context=context)
|
||||
categories = {} #store the different categories of products in preference
|
||||
count = 0
|
||||
for pref in preferences:
|
||||
#For each preference
|
||||
categories.setdefault(pref.product_id.category_id.name, {})
|
||||
#if this product has already been added to the categories dictionnary
|
||||
if pref.product_id.id in categories[pref.product_id.category_id.name]:
|
||||
#we check if for the same product the note has already been added
|
||||
if pref.note not in categories[pref.product_id.category_id.name][pref.product_id.id]:
|
||||
#if it's not the case then we add this to preferences
|
||||
categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
|
||||
#if this product is not in the dictionnay, we add it
|
||||
else:
|
||||
categories[pref.product_id.category_id.name][pref.product_id.id] = {}
|
||||
categories[pref.product_id.category_id.name][pref.product_id.id][pref.note] = pref
|
||||
|
||||
currency = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id
|
||||
|
||||
#For each preferences that we get, we will create the XML structure
|
||||
for key,value in categories.items():
|
||||
xml_pref_1 = etree.Element("div")
|
||||
xml_pref_1.set('class','oe_lunch_30pc')
|
||||
xml_pref_2 = etree.Element("h2")
|
||||
xml_pref_2.text = key
|
||||
xml_pref_1.append(xml_pref_2)
|
||||
i = 0
|
||||
value = value.values()
|
||||
for val in value:
|
||||
for pref in val.values():
|
||||
#We only show 5 preferences per category (or it will be too long)
|
||||
if i==5: break
|
||||
i+=1
|
||||
xml_pref_3 = etree.Element("div")
|
||||
xml_pref_3.set('class','oe_lunch_vignette')
|
||||
xml_pref_1.append(xml_pref_3)
|
||||
|
||||
xml_pref_4 = etree.Element("span")
|
||||
xml_pref_4.set('class','oe_lunch_button')
|
||||
xml_pref_3.append(xml_pref_4)
|
||||
|
||||
xml_pref_5 = etree.Element("button")
|
||||
xml_pref_5.set('name',"add_preference_"+str(pref.id))
|
||||
xml_pref_5.set('class','oe_link oe_i oe_button_plus')
|
||||
xml_pref_5.set('type','object')
|
||||
xml_pref_5.set('string','+')
|
||||
xml_pref_4.append(xml_pref_5)
|
||||
|
||||
xml_pref_6 = etree.Element("button")
|
||||
xml_pref_6.set('name',"add_preference_"+str(pref.id))
|
||||
xml_pref_6.set('class','oe_link oe_button_add')
|
||||
xml_pref_6.set('type','object')
|
||||
xml_pref_6.set('string',_("Add"))
|
||||
xml_pref_4.append(xml_pref_6)
|
||||
|
||||
xml_pref_7 = etree.Element("div")
|
||||
xml_pref_7.set('class','oe_group_text_button')
|
||||
xml_pref_3.append(xml_pref_7)
|
||||
|
||||
xml_pref_8 = etree.Element("div")
|
||||
xml_pref_8.set('class','oe_lunch_text')
|
||||
xml_pref_8.text = escape(pref.product_id.name)+str(" ")
|
||||
xml_pref_7.append(xml_pref_8)
|
||||
|
||||
price = pref.product_id.price or 0.0
|
||||
cur = currency.name or ''
|
||||
xml_pref_9 = etree.Element("span")
|
||||
xml_pref_9.set('class','oe_tag')
|
||||
xml_pref_9.text = str(price)+str(" ")+cur
|
||||
xml_pref_8.append(xml_pref_9)
|
||||
|
||||
xml_pref_10 = etree.Element("div")
|
||||
xml_pref_10.set('class','oe_grey')
|
||||
xml_pref_10.text = escape(pref.note or '')
|
||||
xml_pref_3.append(xml_pref_10)
|
||||
|
||||
xml_start.append(xml_pref_1)
|
||||
|
||||
first_node = doc.xpath("//div[@name='preferences']")
|
||||
if first_node and len(first_node)>0:
|
||||
first_node[0].append(xml_start)
|
||||
res['arch'] = etree.tostring(doc)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'User Name', required=True, \
|
||||
readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'product': fields.many2one('lunch.product', 'Product', required=True, \
|
||||
readonly=True, states={'draft':[('readonly', False)]}, change_default=True),
|
||||
'date': fields.date('Date', readonly=True, states={'draft':[('readonly', False)]}),
|
||||
'cashmove': fields.many2one('lunch.cashmove', 'Cash Move' , readonly=True),
|
||||
'descript': fields.char('Comment', readonly=True, size=250, \
|
||||
states = {'draft':[('readonly', False)]}),
|
||||
'state': fields.selection([('draft', 'New'), ('confirmed', 'Confirmed'), ], \
|
||||
'Status', readonly=True, select=True),
|
||||
'price': fields.function(_price_get, string="Price"),
|
||||
'category': fields.many2one('lunch.category','Category'),
|
||||
'user_id': fields.many2one('res.users', 'User Name', required=True, readonly=True, states={'new':[('readonly', False)]}),
|
||||
'date': fields.date('Date', required=True, readonly=True, states={'new':[('readonly', False)]}),
|
||||
'order_line_ids': fields.one2many('lunch.order.line', 'order_id', 'Products', ondelete="cascade", readonly=True, states={'new':[('readonly', False)]}),
|
||||
'total': fields.function(_price_get, string="Total", store={
|
||||
'lunch.order.line': (_fetch_orders_from_lines, ['product_id','order_id'], 20),
|
||||
}),
|
||||
'state': fields.selection([('new', 'New'), \
|
||||
('confirmed','Confirmed'), \
|
||||
('cancelled','Cancelled'), \
|
||||
('partially','Partially Confirmed')] \
|
||||
,'Status', readonly=True, select=True),
|
||||
'alerts': fields.function(_alerts_get, string="Alerts", type='text'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'user_id': lambda self, cr, uid, context: uid,
|
||||
'date': fields.date.context_today,
|
||||
'state': lambda self, cr, uid, context: 'draft',
|
||||
'state': 'new',
|
||||
'alerts': _default_alerts_get,
|
||||
}
|
||||
|
||||
def confirm(self, cr, uid, ids, box, context=None):
|
||||
|
||||
""" confirm order
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of confirm order’s IDs
|
||||
@param context: A standard dictionary for contextual values """
|
||||
class lunch_order_line(osv.Model):
|
||||
"""
|
||||
lunch order line: one lunch order can have many order lines
|
||||
"""
|
||||
_name = 'lunch.order.line'
|
||||
_description = 'lunch order line'
|
||||
|
||||
def onchange_price(self, cr, uid, ids, product_id, context=None):
|
||||
if product_id:
|
||||
price = self.pool.get('lunch.product').browse(cr, uid, product_id, context=context).price
|
||||
return {'value': {'price': price}}
|
||||
return {'value': {'price': 0.0}}
|
||||
|
||||
def order(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
The order_line is ordered to the supplier but isn't received yet
|
||||
"""
|
||||
for order_line in self.browse(cr, uid, ids, context=context):
|
||||
order_line.write({'state': 'ordered'}, context=context)
|
||||
return self._update_order_lines(cr, uid, ids, context=context)
|
||||
|
||||
def confirm(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
confirm one or more order line, update order status and create new cashmove
|
||||
"""
|
||||
cashmove_ref = self.pool.get('lunch.cashmove')
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
if order.state == 'confirmed':
|
||||
continue
|
||||
new_id = cashmove_ref.create(cr, uid, {'name': order.product.name+' order',
|
||||
'amount':-order.product.price,
|
||||
'user_cashmove':order.user_id.id,
|
||||
'box':box,
|
||||
'active':True,
|
||||
})
|
||||
self.write(cr, uid, [order.id], {'cashmove': new_id, 'state': 'confirmed'})
|
||||
for order_line in self.browse(cr, uid, ids, context=context):
|
||||
if order_line.state != 'confirmed':
|
||||
values = {
|
||||
'user_id': order_line.user_id.id,
|
||||
'amount': -order_line.price,
|
||||
'description': order_line.product_id.name,
|
||||
'order_id': order_line.id,
|
||||
'state': 'order',
|
||||
'date': order_line.date,
|
||||
}
|
||||
cashmove_ref.create(cr, uid, values, context=context)
|
||||
order_line.write({'state': 'confirmed'}, context=context)
|
||||
return self._update_order_lines(cr, uid, ids, context=context)
|
||||
|
||||
def _update_order_lines(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Update the state of lunch.order based on its orderlines
|
||||
"""
|
||||
orders_ref = self.pool.get('lunch.order')
|
||||
orders = []
|
||||
for order_line in self.browse(cr, uid, ids, context=context):
|
||||
orders.append(order_line.order_id)
|
||||
for order in set(orders):
|
||||
isconfirmed = True
|
||||
for orderline in order.order_line_ids:
|
||||
if orderline.state == 'new':
|
||||
isconfirmed = False
|
||||
if orderline.state == 'cancelled':
|
||||
isconfirmed = False
|
||||
orders_ref.write(cr, uid, [order.id], {'state': 'partially'}, context=context)
|
||||
if isconfirmed:
|
||||
orders_ref.write(cr, uid, [order.id], {'state': 'confirmed'}, context=context)
|
||||
return {}
|
||||
|
||||
def lunch_order_cancel(self, cr, uid, ids, context=None):
|
||||
|
||||
"""" cancel order
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of create menu’s IDs
|
||||
@param context: A standard dictionary for contextual values """
|
||||
|
||||
orders = self.browse(cr, uid, ids, context=context)
|
||||
for order in orders:
|
||||
if not order.cashmove:
|
||||
continue
|
||||
if order.cashmove.id:
|
||||
self.pool.get('lunch.cashmove').unlink(cr, uid, [order.cashmove.id])
|
||||
self.write(cr, uid, ids, {'state':'draft'})
|
||||
return {}
|
||||
|
||||
def onchange_product(self, cr, uid, ids, product):
|
||||
|
||||
""" Get price for Product
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of create menu’s IDs
|
||||
@product: Product To Ordered """
|
||||
|
||||
if not product:
|
||||
return {'value': {'price': 0.0}}
|
||||
price = self.pool.get('lunch.product').read(cr, uid, product, ['price'])['price']
|
||||
categ_id = self.pool.get('lunch.product').browse(cr, uid, product).category_id.id
|
||||
return {'value': {'price': price,'category':categ_id}}
|
||||
|
||||
lunch_order()
|
||||
|
||||
|
||||
class report_lunch_amount(osv.osv):
|
||||
""" Lunch Amount Report """
|
||||
|
||||
_name = 'report.lunch.amount'
|
||||
_description = "Amount available by user and box"
|
||||
_auto = False
|
||||
_rec_name = "user_id"
|
||||
def cancel(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
cancel one or more order.line, update order status and unlink existing cashmoves
|
||||
"""
|
||||
cashmove_ref = self.pool.get('lunch.cashmove')
|
||||
for order_line in self.browse(cr, uid, ids, context=context):
|
||||
order_line.write({'state':'cancelled'}, context=context)
|
||||
cash_ids = [cash.id for cash in order_line.cashmove]
|
||||
cashmove_ref.unlink(cr, uid, cash_ids, context=context)
|
||||
return self._update_order_lines(cr, uid, ids, context=context)
|
||||
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'User Name', readonly=True),
|
||||
'amount': fields.float('Amount', readonly=True, digits=(16, 2)),
|
||||
'box': fields.many2one('lunch.cashbox', 'Box Name', size=30, readonly=True),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
|
||||
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
|
||||
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'date': fields.date('Created Date', readonly=True),
|
||||
'name': fields.related('product_id', 'name', readonly=True),
|
||||
'order_id': fields.many2one('lunch.order', 'Order', ondelete='cascade'),
|
||||
'product_id': fields.many2one('lunch.product', 'Product', required=True),
|
||||
'date': fields.related('order_id', 'date', type='date', string="Date", readonly=True, store=True),
|
||||
'supplier': fields.related('product_id', 'supplier', type='many2one', relation='res.partner', string="Supplier", readonly=True, store=True),
|
||||
'user_id': fields.related('order_id', 'user_id', type='many2one', relation='res.users', string='User', readonly=True, store=True),
|
||||
'note': fields.text('Note'),
|
||||
'price': fields.float("Price"),
|
||||
'state': fields.selection([('new', 'New'), \
|
||||
('confirmed', 'Received'), \
|
||||
('ordered', 'Ordered'), \
|
||||
('cancelled', 'Cancelled')], \
|
||||
'Status', readonly=True, select=True),
|
||||
'cashmove': fields.one2many('lunch.cashmove', 'order_id', 'Cash Move', ondelete='cascade'),
|
||||
|
||||
}
|
||||
_defaults = {
|
||||
'state': 'new',
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
|
||||
""" @param cr: the current row, from the database cursor"""
|
||||
class lunch_product(osv.Model):
|
||||
"""
|
||||
lunch product
|
||||
"""
|
||||
_name = 'lunch.product'
|
||||
_description = 'lunch product'
|
||||
_columns = {
|
||||
'name': fields.char('Product', required=True, size=64),
|
||||
'category_id': fields.many2one('lunch.product.category', 'Category', required=True),
|
||||
'description': fields.text('Description', size=256),
|
||||
'price': fields.float('Price', digits=(16,2)), #TODO: use decimal precision of 'Account', move it from product to decimal_precision
|
||||
'supplier': fields.many2one('res.partner', 'Supplier'),
|
||||
}
|
||||
|
||||
cr.execute("""
|
||||
create or replace view report_lunch_amount as (
|
||||
select
|
||||
min(lc.id) as id,
|
||||
to_date(to_char(lc.create_date, 'dd-MM-YYYY'),'dd-MM-YYYY') as date,
|
||||
to_char(lc.create_date, 'YYYY') as year,
|
||||
to_char(lc.create_date, 'MM') as month,
|
||||
to_char(lc.create_date, 'YYYY-MM-DD') as day,
|
||||
lc.user_cashmove as user_id,
|
||||
sum(amount) as amount,
|
||||
lc.box as box
|
||||
from
|
||||
lunch_cashmove lc
|
||||
where
|
||||
active = 't'
|
||||
group by lc.user_cashmove, lc.box, lc.create_date
|
||||
)""")
|
||||
class lunch_product_category(osv.Model):
|
||||
"""
|
||||
lunch product category
|
||||
"""
|
||||
_name = 'lunch.product.category'
|
||||
_description = 'lunch product category'
|
||||
_columns = {
|
||||
'name': fields.char('Category', required=True), #such as PIZZA, SANDWICH, PASTA, CHINESE, BURGER, ...
|
||||
}
|
||||
|
||||
report_lunch_amount()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
class lunch_cashmove(osv.Model):
|
||||
"""
|
||||
lunch cashmove => order or payment
|
||||
"""
|
||||
_name = 'lunch.cashmove'
|
||||
_description = 'lunch cashmove'
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'User Name', required=True),
|
||||
'date': fields.date('Date', required=True),
|
||||
'amount': fields.float('Amount', required=True), #depending on the kind of cashmove, the amount will be positive or negative
|
||||
'description': fields.text('Description'), #the description can be an order or a payment
|
||||
'order_id': fields.many2one('lunch.order.line', 'Order', ondelete='cascade'),
|
||||
'state': fields.selection([('order','Order'), ('payment','Payment')], 'Is an order or a Payment'),
|
||||
}
|
||||
_defaults = {
|
||||
'user_id': lambda self, cr, uid, context: uid,
|
||||
'date': fields.date.context_today,
|
||||
'state': 'payment',
|
||||
}
|
||||
|
||||
class lunch_alert(osv.Model):
|
||||
"""
|
||||
lunch alert
|
||||
"""
|
||||
_name = 'lunch.alert'
|
||||
_description = 'Lunch Alert'
|
||||
_columns = {
|
||||
'message': fields.text('Message', size=256, required=True),
|
||||
'alter_type': fields.selection([('specific', 'Specific Day'), \
|
||||
('week', 'Every Week'), \
|
||||
('days', 'Every Day')], \
|
||||
string='Recurrency', required=True, select=True),
|
||||
'specific_day': fields.date('Day'),
|
||||
'monday': fields.boolean('Monday'),
|
||||
'tuesday': fields.boolean('Tuesday'),
|
||||
'wednesday': fields.boolean('Wednesday'),
|
||||
'thursday': fields.boolean('Thursday'),
|
||||
'friday': fields.boolean('Friday'),
|
||||
'saturday': fields.boolean('Saturday'),
|
||||
'sunday': fields.boolean('Sunday'),
|
||||
'active_from': fields.float('Between', required=True),
|
||||
'active_to': fields.float('And', required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'alter_type': 'specific',
|
||||
'specific_day': fields.date.context_today,
|
||||
'active_from': 7,
|
||||
'active_to': 23,
|
||||
}
|
||||
|
|
|
@ -2,23 +2,180 @@
|
|||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="lunch.category" id="categ_sandwich">
|
||||
<record id="base.user_root" model="res.users">
|
||||
<field name="groups_id" eval="[(4,ref('lunch.group_lunch_manager'))]"/>
|
||||
</record>
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field name="groups_id" eval="[(4,ref('lunch.group_lunch_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product.category" id="categ_sandwich">
|
||||
<field name="name">Sandwich</field>
|
||||
</record>
|
||||
<record model="lunch.product.category" id="categ_pizza">
|
||||
<field name="name">Pizza</field>
|
||||
</record>
|
||||
<record model="lunch.product.category" id="categ_pasta">
|
||||
<field name="name">Pasta</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_club">
|
||||
<field name="name">Club</field>
|
||||
<record model="res.partner" id="partner_coin_gourmand">
|
||||
<field name="name">Coin gourmand</field>
|
||||
<field name="supplier_lunch">True</field>
|
||||
</record>
|
||||
|
||||
<record model="res.partner" id="partner_pizza_inn">
|
||||
<field name="name">Pizza Inn</field>
|
||||
<field name="supplier_lunch">True</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_cheese_ham">
|
||||
<field name="name">Cheese And Ham</field>
|
||||
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
|
||||
<field name="price">2.75</field>
|
||||
<field name="price">3.30</field>
|
||||
<field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
|
||||
<field name="description">Cheese, Ham, Salad, Tomatoes, cucumbers, eggs</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.cashbox" id="cashbox_cashbox">
|
||||
<field name="name">Cashbox</field>
|
||||
<field name="manager" ref="base.user_root"/>
|
||||
<record model="lunch.product" id="product_country">
|
||||
<field name="name">The Country</field>
|
||||
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
|
||||
<field name="price">3.30</field>
|
||||
<field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
|
||||
<field name="description">Brie, Honey, Walnut Kernels</field>
|
||||
</record>
|
||||
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field name="groups_id" eval="[(4,ref('base.group_tool_user'))]"/>
|
||||
<record model="lunch.product" id="product_tuna">
|
||||
<field name="name">Tuna</field>
|
||||
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
|
||||
<field name="price">2.50</field>
|
||||
<field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
|
||||
<field name="description">Tuna, Mayonnaise</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_gouda">
|
||||
<field name="name">Gouda Cheese</field>
|
||||
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
|
||||
<field name="price">2.50</field>
|
||||
<field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
|
||||
<field name="description"></field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_chicken_curry">
|
||||
<field name="name">Chicken Curry</field>
|
||||
<field name="category_id" eval="str(ref('categ_sandwich'))"/>
|
||||
<field name="price">2.60</field>
|
||||
<field name="supplier" eval="str(ref('partner_coin_gourmand'))"/>
|
||||
<field name="description"></field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_margherita">
|
||||
<field name="name">Pizza Margherita</field>
|
||||
<field name="category_id" eval="str(ref('categ_pizza'))"/>
|
||||
<field name="price">6.90</field>
|
||||
<field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
|
||||
<field name="description">Tomatoes, Mozzarella</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_italiana">
|
||||
<field name="name">Pizza Italiana</field>
|
||||
<field name="category_id" eval="str(ref('categ_pizza'))"/>
|
||||
<field name="price">7.40</field>
|
||||
<field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
|
||||
<field name="description">Fresh Tomatoes, Basil, Mozzarella</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_Bolognese">
|
||||
<field name="name">Bolognese Pasta</field>
|
||||
<field name="category_id" eval="str(ref('categ_pasta'))"/>
|
||||
<field name="price">7.70</field>
|
||||
<field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
|
||||
<field name="description"></field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.product" id="product_Napoli">
|
||||
<field name="name">Napoli Pasta</field>
|
||||
<field name="category_id" eval="str(ref('categ_pasta'))"/>
|
||||
<field name="price">7.70</field>
|
||||
<field name="supplier" eval="str(ref('partner_pizza_inn'))"/>
|
||||
<field name="description">Tomatoes, Basil</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order" id="order_1">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="date" eval="time.strftime('2012-10-23')"/>
|
||||
<field name="order_line_ids" eval="[]"/>
|
||||
<field name="state">new</field>
|
||||
<field name='company_id'>1</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order" id="order_2">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="date" eval="time.strftime('2012-10-22')"/>
|
||||
<field name="order_line_ids" eval="[]"/>
|
||||
<field name="state">confirmed</field>
|
||||
<field name='company_id'>1</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order" id="order_3">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="date" eval="time.strftime('2012-10-24')"/>
|
||||
<field name="order_line_ids" eval="[]"/>
|
||||
<field name="state">cancelled</field>
|
||||
<field name='company_id'>1</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_1">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="product_id" ref="product_Bolognese"/>
|
||||
<field name="date" eval="time.strftime('2012-10-23')"/>
|
||||
<field name="state">new</field>
|
||||
<field name="supplier" ref="partner_pizza_inn"/>
|
||||
<field name="note">+Emmental</field>
|
||||
<field name="order_id" ref="order_1"/>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_2">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="product_id" ref="product_italiana"/>
|
||||
<field name="date" eval="time.strftime('2012-10-22')"/>
|
||||
<field name="state">confirmed</field>
|
||||
<field name="supplier" ref="partner_pizza_inn"/>
|
||||
<field name="note">+Mushrooms</field>
|
||||
<field name="order_id" ref="order_2"/>
|
||||
</record>
|
||||
|
||||
<record model="lunch.order.line" id="order_line_3">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="product_id" ref="product_gouda"/>
|
||||
<field name="date" eval="time.strftime('2012-10-24')"/>
|
||||
<field name="state">cancelled</field>
|
||||
<field name="supplier" ref="partner_coin_gourmand"/>
|
||||
<field name="note">+Salad +Tomatoes +Cucumbers</field>
|
||||
<field name="order_id" ref="order_3"/>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="lunch.cashmove" id="cashmove_1">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="date" eval="time.strftime('2012-10-23')"/>
|
||||
<field name="description">Pizza Italiana</field>
|
||||
<field name="amount">-7.40</field>
|
||||
<field name="order_id" ref="order_2"/>
|
||||
<field name="state">order</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.cashmove" id="cashmove_2">
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="date" eval="time.strftime('2012-10-24')"/>
|
||||
<field name="description">Payment: 5 lunch tickets (6€)</field>
|
||||
<field name="amount">30</field>
|
||||
<field name="state">payment</field>
|
||||
</record>
|
||||
|
||||
<record model="lunch.alert" id="alert_1">
|
||||
<field name="message">Lunch must be ordered before 10h30 am</field>
|
||||
<field name="day">days</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
<openerp>
|
||||
<data>
|
||||
<record model="ir.actions.act_window" id="view_lunch_product_form_installer">
|
||||
<field name="name">Define Your Lunch Products</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">lunch.product</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a new product that can be ordered for the lunch.
|
||||
</p><p>
|
||||
We suggest you to put the real price so that the exact due
|
||||
amount is deduced from each employee's cash boxes when they
|
||||
order.
|
||||
</p><p>
|
||||
If you order lunch at several places, you can use the product
|
||||
categories to split by supplier. It will be easier to filter
|
||||
lunch orders.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_lunch_product_form_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="view_lunch_product_form_installer"/>
|
||||
<field name="sequence">50</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_create_cashbox">
|
||||
<field name="name">Create Lunch Cash Boxes</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">lunch.cashbox</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a new cash box.
|
||||
</p><p>
|
||||
You can create on cash box by employee if you want to keep
|
||||
track of the amount due by employee according to what have been
|
||||
ordered.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_create_cashbox_todo" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_create_cashbox" />
|
||||
<field name="sequence">51</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -4,8 +4,8 @@
|
|||
<report
|
||||
id="report_lunch_order"
|
||||
string="Lunch Order"
|
||||
model="lunch.order"
|
||||
name="lunch.order"
|
||||
model="lunch.order.line"
|
||||
name="lunch.order.line"
|
||||
rml="lunch/report/order.rml"
|
||||
auto="False"
|
||||
/>
|
||||
|
|
|
@ -1,393 +1,486 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Top menu item -->
|
||||
<menuitem name="Tools" id="base.menu_tools" sequence="160"/>
|
||||
<!--Menu and Title-->
|
||||
<menuitem id='menu_lunch' name='Lunch' sequence="300"/>
|
||||
<menuitem name="Lunch" parent="menu_lunch" id="menu_lunch_title" sequence="50" />
|
||||
<menuitem name="Administrate Orders" parent="menu_lunch" id="menu_lunch_admin" sequence="51" groups="group_lunch_manager"/>
|
||||
<menuitem name="Administrate Cash Moves" parent="menu_lunch" id="menu_lunch_cash" sequence="52" groups="group_lunch_manager"/>
|
||||
<menuitem name="Configuration" parent="menu_lunch" id="menu_lunch_config" sequence="53" groups="group_lunch_manager"/>
|
||||
|
||||
<!--View Search to group/filter by Supplier and time-->
|
||||
<record model="ir.ui.view" id="lunch_order_line_search_view">
|
||||
<field name="name">Search</field>
|
||||
<field name="model">lunch.order.line</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search">
|
||||
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('note', 'ilike', self)]"/>
|
||||
<filter name="not_confirmed" string="Not Received" domain="[('state','!=',('confirmed'))]"/>
|
||||
<filter name="comfirmed" string="Received" domain="[('state','=','confirmed')]"/>
|
||||
<filter name="cancelled" string="Cancelled" domain="[('state','=','cancelled')]"/>
|
||||
<separator/>
|
||||
<filter name="today" string="Today" domain="[('date','=',time.strftime('%%Y-%%m-%%d'))]"/>
|
||||
<field name="user_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter name="group_by_supplier" string="By Supplier" context="{'group_by':'supplier'}"/>
|
||||
<filter name="group_by_date" string="By Date" context="{'group_by':'date'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Lunch Order" parent="base.menu_tools"
|
||||
id="menu_lunch" sequence="1" />
|
||||
<!--View Search to group by employee and input/output (cashmoves)-->
|
||||
<record id="view_lunch_employee_payment_filter" model="ir.ui.view">
|
||||
<field name='name'>lunch employee payment</field>
|
||||
<field name='model'>lunch.cashmove</field>
|
||||
<field name='type'>search</field>
|
||||
<field name='arch' type='xml'>
|
||||
<search string="lunch employee payment">
|
||||
<field name="description"/>
|
||||
<field name="user_id"/>
|
||||
<filter name='is_payment' string="Payment" domain="[('state','=','payment')]"/>
|
||||
<separator/>
|
||||
<filter name='is_mine' string="My Account" domain="[('user_id','=',uid)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Reporting" parent="base.menu_tools"
|
||||
id="base.menu_lunch_reporting" sequence="6" groups="base.group_tool_manager"/>
|
||||
<record id="view_lunch_cashmove_filter" model="ir.ui.view">
|
||||
<field name='name'>lunch cashmove</field>
|
||||
<field name='model'>lunch.cashmove</field>
|
||||
<field name='type'>search</field>
|
||||
<field name='arch' type='xml'>
|
||||
<search string="lunch cashmove">
|
||||
<field name="description"/>
|
||||
<field name="user_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter name='group_by_user' string="By Employee" context="{'group_by':'user_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Lunch"
|
||||
parent="base.menu_reporting"
|
||||
id="menu_lunch_reporting_order" sequence="55" />
|
||||
<!--View search for order-->
|
||||
<record id="view_search_my_order" model="ir.ui.view">
|
||||
<field name='name'>lunch orders</field>
|
||||
<field name='model'>lunch.order</field>
|
||||
<field name='type'>search</field>
|
||||
<field name='arch' type='xml'>
|
||||
<search string="lunch orders">
|
||||
<field name="date"/>
|
||||
<field name="order_line_ids"/>
|
||||
<filter name='is_mine' string="My Orders" domain="[('user_id','=',uid)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Configuration" parent="base.menu_tools"
|
||||
id="base.menu_lunch_survey_root" sequence="20" groups="base.group_tool_manager"/>
|
||||
|
||||
<menuitem name="Lunch" parent="base.menu_lunch_survey_root"
|
||||
id="menu_lunch_category_root_configuration" sequence="1" />
|
||||
<record model="ir.ui.view" id="alert_search_view">
|
||||
<field name="name">Search</field>
|
||||
<field name="model">lunch.alert</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search">
|
||||
<field name="message"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch order Form view -->
|
||||
<!--Action for Your Orders-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_order_form">
|
||||
<field name="name">New Order</field>
|
||||
<field name="res_model">lunch.order</field>
|
||||
<field name="view_mode">form</field>
|
||||
</record>
|
||||
<menuitem name="New Order" parent="menu_lunch_title" id="menu_lunch_order_form" action="action_lunch_order_form" sequence="1"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_order_form">
|
||||
<field name="name">Order</field>
|
||||
<record model="ir.actions.act_window" id="action_lunch_order_tree">
|
||||
<field name="name">Your Orders</field>
|
||||
<field name="res_model">lunch.order</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_search_my_order"/>
|
||||
<field name="context">{"search_default_is_mine":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a lunch order.
|
||||
</p>
|
||||
<p>
|
||||
A lunch order is defined by its user, date and order lines.
|
||||
Each order line corresponds to a product, an additional note and a price.
|
||||
Before selecting your order lines, don't forget to read the warnings displayed in the reddish area.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Previous Orders" parent="menu_lunch_title" id="menu_lunch_order_tree" action="action_lunch_order_tree" sequence="2"/>
|
||||
|
||||
<!--Action for Lunch cashmoves-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_cashmove_form">
|
||||
<field name="name">Your Account</field>
|
||||
<field name="res_model">lunch.cashmove</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
|
||||
<field name="context">{"search_default_is_mine":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here you can see your cash moves.<br/>A cash moves can be either an expense or a payment.
|
||||
An expense is automatically created when an order is received while a payment is a reimbursement to the company encoded by the manager.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Your Lunch Account" parent="menu_lunch_title" id="menu_lunch_cashmove_form" action="action_lunch_cashmove_form" sequence="3"/>
|
||||
|
||||
<!--Action for Administrate Orders group by supplier-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_order_by_supplier_form">
|
||||
<field name="name">Orders by Supplier</field>
|
||||
<field name="res_model">lunch.order.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="search_view_id" ref="lunch_order_line_search_view"/>
|
||||
<field name="context">{"search_default_group_by_supplier":1, "search_default_today":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here you can see today's orders grouped by suppliers.
|
||||
</p>
|
||||
<p>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> to announce that the order isn't available
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Today's Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_order_by_supplier_form" action="action_lunch_order_by_supplier_form" />
|
||||
|
||||
<!--Action for control Supplier-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_control_suppliers">
|
||||
<field name="name">Control Suppliers</field>
|
||||
<field name="res_model">lunch.order.line</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="search_view_id" ref="lunch_order_line_search_view"/>
|
||||
<field name="context">{"search_default_group_by_date":1, "search_default_group_by_supplier":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
Here you can see every orders grouped by suppliers and by date.
|
||||
</p>
|
||||
<p>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/terp-call-start.png"/> to announce that the order is ordered <br/>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/gtk-apply.png"/> to announce that the order is received <br/>
|
||||
- Click on the <img src="../../../web/static/src/img/icons/gtk-cancel.png"/> red X to announce that the order isn't available
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Orders by Supplier" parent="menu_lunch_admin" id="menu_lunch_control_suppliers" action="action_lunch_control_suppliers" />
|
||||
|
||||
<!--Action for Control Accounts-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_control_accounts">
|
||||
<field name="name">Control Accounts</field>
|
||||
<field name="res_model">lunch.cashmove</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_lunch_cashmove_filter"/>
|
||||
<field name="context">{"search_default_group_by_user":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new payment.
|
||||
</p>
|
||||
<p>
|
||||
A cashmove can either be an expense or a payment.<br/>
|
||||
An expense is automatically created at the order receipt.<br/>
|
||||
A payment represents the employee reimbursement to the company.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Control Accounts" parent="menu_lunch_cash" id="menu_lunch_control_accounts" action="action_lunch_control_accounts" />
|
||||
|
||||
|
||||
<!--Action for Payment cashmove-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_cashmove">
|
||||
<field name="name">Register Cash Moves</field>
|
||||
<field name="res_model">lunch.cashmove</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_lunch_employee_payment_filter"/>
|
||||
<field name="context">{"search_default_is_payment":1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a payment.
|
||||
</p>
|
||||
<p>
|
||||
Here you can see the employees' payment. A payment is a cash move from the employee to the company.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Employee's Payment" parent="menu_lunch_cash" id="menu_lunch_cashmove" action="action_lunch_cashmove" />
|
||||
|
||||
<!--Action for Products-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_products">
|
||||
<field name="name">Products</field>
|
||||
<field name="res_model">lunch.product</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a product for lunch.
|
||||
</p>
|
||||
<p>
|
||||
A product is defined by its name, category, price and supplier.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Products" parent="menu_lunch_config" id="menu_lunch_products" action="action_lunch_products" />
|
||||
|
||||
<!--Action for Product categories-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_product_categories">
|
||||
<field name="name">Product Categories</field>
|
||||
<field name="res_model">lunch.product.category</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a lunch category.
|
||||
</p>
|
||||
<p>
|
||||
Here you can find every lunch categories for products.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_category_form_view">
|
||||
<field name="name">Product category Form</field>
|
||||
<field name="model">lunch.product.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Products Form" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name='name' string="Product Category: "/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Product Categories" parent="menu_lunch_config" id="menu_lunch_product_categories" action="action_lunch_product_categories" />
|
||||
|
||||
<!--Action for Alert-->
|
||||
<record model="ir.actions.act_window" id="action_lunch_alert">
|
||||
<field name="name">Alerts</field>
|
||||
<field name="res_model">lunch.alert</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="alert_search_view"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a lunch alert.
|
||||
</p>
|
||||
<p>
|
||||
Alerts are used to warn employee from possible issues concerning the lunch orders.
|
||||
To create a lunch alert you have to define its recurrency, the time interval during which the alert should be executed and the message to display.
|
||||
</p>
|
||||
<p>
|
||||
Example: <br/>
|
||||
- Recurency: Everyday<br/>
|
||||
- Time interval: from 00h00 am to 11h59 pm<br/>
|
||||
- Message: "You must order before 10h30 am"
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem name="Alerts" parent="menu_lunch_config" id="menu_lunch_alert" action="action_lunch_alert" />
|
||||
|
||||
<!--View for Order lines-->
|
||||
<record model="ir.ui.view" id="orders_order_lines_tree_view">
|
||||
<field name="name">Order lines Tree</field>
|
||||
<field name="model">lunch.order.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Order lines Tree">
|
||||
<field name='date'/>
|
||||
<field name='user_id'/>
|
||||
<field name='supplier' invisible='1'/>
|
||||
<field name='product_id'/>
|
||||
<field name='note'/>
|
||||
<field name='state'/>
|
||||
<field name='price' sum="Total"/>
|
||||
<button name="order" string="Order" type="object" icon="terp-call-start" attrs="{'invisible': ['|',('state','=','confirmed'),('state','=','ordered')]}"/>
|
||||
<button name="confirm" string="Confirm" type="object" icon="gtk-apply" attrs="{'invisible': [('state','!=','ordered')]}"/>
|
||||
<button name="cancel" string="Cancel" type="object" icon="gtk-cancel" attrs="{'invisible': [('state','=','cancelled')]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--View for Your orders-->
|
||||
<record model="ir.ui.view" id="orders_tree_view">
|
||||
<field name="name">Orders Tree View</field>
|
||||
<field name="model">lunch.order</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Orders Tree">
|
||||
<field name="date"/>
|
||||
<field name="order_line_ids"/>
|
||||
<field name="state" />
|
||||
<field name="total" sum="Total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="orders_form_view">
|
||||
<field name="name">Lunch Order</field>
|
||||
<field name="model">lunch.order</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Lunch Order" version="7.0">
|
||||
<header>
|
||||
<button name="%(action_lunch_order_confirm)d" string="Confirm Order" type="action" states="draft" class="oe_highlight"/>
|
||||
<button name="%(action_lunch_order_cancel)d" string="Cancel Order" type="action" states="confirmed" />
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed"/>
|
||||
</header>
|
||||
<sheet string="Order">
|
||||
<group>
|
||||
<form string='Orders Form' version='7.0' class="oe_lunch">
|
||||
<header>
|
||||
<field name='state' widget='statusbar' statusbar_visible='new,confirmed'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="product" on_change="onchange_product(product)"/>
|
||||
<field name="descript"/>
|
||||
<field name="price"/>
|
||||
<field name="category"/>
|
||||
<group>
|
||||
<field name='user_id'/>
|
||||
</group>
|
||||
<group>
|
||||
<field name='date'/>
|
||||
</group>
|
||||
</group>
|
||||
<field name='alerts' attrs="{'invisible': ['|',('state','!=','new'),('alerts','=','')]}" class="oe_inline oe_lunch_alert"/>
|
||||
<div name="preferences">
|
||||
</div>
|
||||
<separator string='Select your order'/>
|
||||
<field name='order_line_ids' nolabel='1' on_change='onchange_price(order_line_ids)'>
|
||||
<tree string='List' editable='bottom'>
|
||||
<field name='product_id' on_change='onchange_price(product_id)'/>
|
||||
<field name='note' />
|
||||
<field name='price' />
|
||||
<field name='supplier' invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group class='oe_subtotal_footer oe_right'>
|
||||
<field name='total'/>
|
||||
</group>
|
||||
<br/><br/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--View for Products-->
|
||||
<record model="ir.ui.view" id="products_tree_view">
|
||||
<field name="name">Products Tree</field>
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Products Tree">
|
||||
<field name="name"/>
|
||||
<field name="category_id"/>
|
||||
<field name="supplier"/>
|
||||
<field name="description"/>
|
||||
<field name="price"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="products_form_view">
|
||||
<field name="name">Products Form</field>
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Products Form" version="7.0">
|
||||
<header>
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name='name'/>
|
||||
<field name='category_id'/>
|
||||
<field name='supplier'/>
|
||||
<field name='price'/>
|
||||
</group>
|
||||
<label for='description'/>
|
||||
<field name='description'/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--view for cashmove-->
|
||||
<record model="ir.ui.view" id="casmove_tree_view">
|
||||
<field name="name">cashmove tree</field>
|
||||
<field name="model">lunch.cashmove</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="cashmove tree">
|
||||
<field name="date"/>
|
||||
<field name="user_id"/>
|
||||
<field name="description"/>
|
||||
<field name="amount" sum="Total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="casmove_form_view">
|
||||
<field name="name">cashmove form</field>
|
||||
<field name="model">lunch.cashmove</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="cashmove form" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
<field name="cashmove"/>
|
||||
<field name="date"/>
|
||||
<field name="amount"/>
|
||||
</group>
|
||||
</group>
|
||||
<label for='description'/>
|
||||
<field name="description"/>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--view for alerts-->
|
||||
<record model="ir.ui.view" id="alert_tree_view">
|
||||
<field name="name">alert tree</field>
|
||||
<field name="model">lunch.alert</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="alert tree">
|
||||
<field name="message"/>
|
||||
<field name="alter_type"/>
|
||||
<field name='active_from' widget='float_time'/>
|
||||
<field name='active_to' widget='float_time'/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="alert_form_view">
|
||||
<field name="name">alert form</field>
|
||||
<field name="model">lunch.alert</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="alert tree" version="7.0">
|
||||
<sheet>
|
||||
<group string="Schedule Date">
|
||||
<group>
|
||||
<field name="alter_type"/>
|
||||
<field name="specific_day" attrs="{'invisible': [('alter_type','!=','specific')], 'required':[('alter_type','=','specific')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('alter_type','!=','week')]}">
|
||||
<group>
|
||||
<field name="monday"/>
|
||||
<field name="tuesday"/>
|
||||
<field name="wednesday"/>
|
||||
<field name="thursday"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="friday"/>
|
||||
<field name="saturday"/>
|
||||
<field name="sunday"/>
|
||||
</group>
|
||||
</group>
|
||||
<group string="Schedule Hour">
|
||||
<field name='active_from' widget='float_time'/>
|
||||
<field name='active_to' widget='float_time'/>
|
||||
</group>
|
||||
<group string='Message'>
|
||||
<field name='message' nolabel='1' placeholder="Write the message you want to display during the defined period..."/>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch order Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_order_tree">
|
||||
<field name="name">Order</field>
|
||||
<field name="model">lunch.order</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state == 'draft';black:state == 'confirmed'" string="Order">
|
||||
<field name="date"/>
|
||||
<field name="user_id"/>
|
||||
<field name="product"/>
|
||||
<field name="descript"/>
|
||||
<field name="category"/>
|
||||
<field name="price" sum="Total price"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch order Search view -->
|
||||
|
||||
<record id="view_lunch_order_filter" model="ir.ui.view">
|
||||
<field name="name">lunch.order.list.select</field>
|
||||
<field name="model">lunch.order</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Lunch Order">
|
||||
<field name="date"/>
|
||||
<filter icon="terp-check" string="To Confirm" domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-camera_test" string="Confirmed" domain="[('state','=',('confirmed'))]"/>
|
||||
<field name="user_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Category" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'category'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch order Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_lunch_order_form">
|
||||
<field name="name">Lunch Orders</field>
|
||||
<field name="res_model">lunch.order</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_lunch_order_filter"/>
|
||||
<field name="context">{"search_default_Today":1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Lunch Orders" parent="menu_lunch"
|
||||
id="menu_lunch_order_form" action="action_lunch_order_form" />
|
||||
|
||||
<!-- Cash Box Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_cashbox_form">
|
||||
<field name="name">Cashboxes</field>
|
||||
<field name="model">lunch.cashbox</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Cashboxes" version="7.0">
|
||||
<group colspan="4">
|
||||
<field name="name"/>
|
||||
<field name="manager"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Cash Box Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_cashbox_tree">
|
||||
<field name="name">Cashboxes</field>
|
||||
<field name="model">lunch.cashbox</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Cashboxes" colors="red:sum_remain<=0">
|
||||
<field name="name"/>
|
||||
<field name="manager"/>
|
||||
<field name="sum_remain"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Cash Box Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_lunch_cashbox_form">
|
||||
<field name="name"> Cashboxes </field>
|
||||
<field name="res_model">lunch.cashbox</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Cashboxes"
|
||||
parent="menu_lunch_category_root_configuration"
|
||||
id="menu_lunch_cashbox_form"
|
||||
action="action_lunch_cashbox_form" />
|
||||
|
||||
<!-- Cash Move Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_cashmove_form">
|
||||
<field name="name">CashMove</field>
|
||||
<field name="model">lunch.cashmove</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="CashMove" version="7.0">
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="name"/>
|
||||
<field name="user_cashmove"/>
|
||||
<field name="amount"/>
|
||||
<field name="box"/>
|
||||
<field name="create_date"/>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Cash Move Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_cashmove_tree">
|
||||
<field name="name">CashMove</field>
|
||||
<field name="model">lunch.cashmove</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="CashMove" editable="top">
|
||||
<field name="create_date"/>
|
||||
<field name="box"/>
|
||||
<field name="name" required="1"/>
|
||||
<field name="user_cashmove"/>
|
||||
<field name="amount" sum="Total amount"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Cash Move Search View -->
|
||||
|
||||
<record id="view_lunch_cashmove_filter" model="ir.ui.view">
|
||||
<field name="name">lunch.cashmove.list.select</field>
|
||||
<field name="model">lunch.cashmove</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search CashMove">
|
||||
<field name="create_date"/>
|
||||
<field name="user_cashmove"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_cashmove'}"/>
|
||||
<filter string="Box" icon="terp-dolar" domain="[]" context="{'group_by':'box'}"/>
|
||||
<filter string="Date" icon="terp-go-today" domain="[]" context="{'group_by':'create_date'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Cash Move Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_lunch_cashmove_form">
|
||||
<field name="name">Cash Moves</field>
|
||||
<field name="res_model">lunch.cashmove</field>
|
||||
<field name="search_view_id" ref="view_lunch_cashmove_filter"/>
|
||||
<field name="context">{"search_default_Today":1}</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Cash Moves" parent="menu_lunch"
|
||||
id="menu_lunch_cashmove_form"
|
||||
action="action_lunch_cashmove_form" />
|
||||
|
||||
<!-- Lunch Category Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_category_form">
|
||||
<field name="name"> Category of product </field>
|
||||
<field name="model">lunch.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Category" version="7.0">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Category Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_category_tree">
|
||||
<field name="name">Category</field>
|
||||
<field name="model">lunch.category</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Order">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Category Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_lunch_category_form">
|
||||
<field name="name"> Product Categories </field>
|
||||
<field name="res_model">lunch.category</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Product Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_product_form">
|
||||
<field name="name">Products</field>
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Products" version="7.0">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="category_id"/>
|
||||
<field name="price" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="active"/>
|
||||
</group>
|
||||
<field name="description" placeholder="Add a description" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Product Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_product_tree">
|
||||
<field name="name">Products</field>
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Products">
|
||||
<field name="name"/>
|
||||
<field name="category_id"/>
|
||||
<field name="price"/>
|
||||
<field name="description"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Product Search view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_lunch_product_search">
|
||||
<field name="name">Products</field>
|
||||
<field name="model">lunch.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Products">
|
||||
<field name="name" string="Product"/>
|
||||
<field name="price"/>
|
||||
<field name="category_id"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Product Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_lunch_product_form">
|
||||
<field name="name">Products</field>
|
||||
<field name="res_model">lunch.product</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_lunch_product_tree"/>
|
||||
<field name="search_view_id" ref="view_lunch_product_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Products"
|
||||
parent="menu_lunch_category_root_configuration"
|
||||
id="menu_lunch_product_form" action="action_lunch_product_form"
|
||||
sequence="2" />
|
||||
|
||||
<menuitem name="Product Categories"
|
||||
parent="menu_lunch_category_root_configuration"
|
||||
id="menu_lunch_category_form"
|
||||
action="action_lunch_category_form" sequence="1" />
|
||||
|
||||
|
||||
<!-- Lunch Amount Tree view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_report_lunch_amount_tree">
|
||||
<field name="name">Lunch amount</field>
|
||||
<field name="model">report.lunch.amount</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Box Amount by User">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
<field name="day" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="box"/>
|
||||
<field name="user_id"/>
|
||||
<field name="amount" sum="Total box" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Amount Form view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_report_lunch_amount_form">
|
||||
<field name="name">Lunch amount</field>
|
||||
<field name="model">report.lunch.amount</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Box Amount by User" version="7.0">
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="user_id"/>
|
||||
<field name="box"/>
|
||||
<field name="amount"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Amount Search view -->
|
||||
|
||||
<record model="ir.ui.view" id="view_report_lunch_amount_search">
|
||||
<field name="name">Lunch amount</field>
|
||||
<field name="model">report.lunch.amount</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Box Amount by User">
|
||||
<field name="date"/>
|
||||
<field name="box"/>
|
||||
<field name="amount"/>
|
||||
<field name="user_id"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Box" icon="terp-dolar" context="{'group_by':'box'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Lunch Amount Action -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_report_lunch_amount_tree">
|
||||
<field name="name">Cash Position by User</field>
|
||||
<field name="res_model">report.lunch.amount</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_year': 1,"search_default_month":1}</field>
|
||||
<field name="search_view_id" ref="view_report_lunch_amount_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="Cash Position by User"
|
||||
parent="menu_lunch_reporting_order"
|
||||
action="action_report_lunch_amount_tree"
|
||||
id="menu_lunch_report_amount_tree" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue