[MERGE] forward port branch 11.0 up to ad825b673b
This commit is contained in:
@@ -394,7 +394,8 @@ class ResPartner(models.Model):
|
||||
required=True)
|
||||
property_account_position_id = fields.Many2one('account.fiscal.position', company_dependent=True,
|
||||
string="Fiscal Position",
|
||||
help="The fiscal position will determine taxes and accounts used for the partner.", oldname="property_account_position")
|
||||
help="The fiscal position will determine taxes and accounts used for the partner.", oldname="property_account_position",
|
||||
domain="[('company_id', 'in', [company_id, False])]")
|
||||
property_payment_term_id = fields.Many2one('account.payment.term', company_dependent=True,
|
||||
string='Customer Payment Terms',
|
||||
help="This payment term will be used instead of the default one for sales orders and customer invoices", oldname="property_payment_term")
|
||||
@@ -441,3 +442,8 @@ class ResPartner(models.Model):
|
||||
action['domain'] = literal_eval(action['domain'])
|
||||
action['domain'].append(('partner_id', 'child_of', self.id))
|
||||
return action
|
||||
|
||||
@api.onchange('company_id')
|
||||
def _onchange_company_id(self):
|
||||
if self.company_id:
|
||||
return {'domain': {'property_account_position_id': [('company_id', 'in', [self.company_id.id, False])]}}
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="email" position="after">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="property_payment_term_id" widget="selection"/>
|
||||
<field name="property_account_position_id" options="{'no_create': True, 'no_open': True}"/>
|
||||
</field>
|
||||
|
||||
@@ -18,24 +18,26 @@ class TaxAdjustments(models.TransientModel):
|
||||
debit_account_id = fields.Many2one('account.account', string='Debit account', required=True, domain=[('deprecated', '=', False)])
|
||||
credit_account_id = fields.Many2one('account.account', string='Credit account', required=True, domain=[('deprecated', '=', False)])
|
||||
amount = fields.Monetary(currency_field='company_currency_id', required=True)
|
||||
adjustment_type = fields.Selection([('debit', 'Adjustment in favor of the Estate'), ('credit', 'Adjustment in your favor')], string="Adjustment Type", store=False, required=True)
|
||||
company_currency_id = fields.Many2one('res.currency', readonly=True, default=lambda self: self.env.user.company_id.currency_id)
|
||||
tax_id = fields.Many2one('account.tax', string='Adjustment Tax', ondelete='restrict', domain=[('type_tax_use', '=', 'adjustment')], required=True)
|
||||
|
||||
@api.multi
|
||||
def _create_move(self):
|
||||
adjustment_type = self.env.context.get('adjustment_type', (self.amount > 0.0 and 'debit' or 'credit'))
|
||||
debit_vals = {
|
||||
'name': self.reason,
|
||||
'debit': self.amount,
|
||||
'debit': abs(self.amount),
|
||||
'credit': 0.0,
|
||||
'account_id': self.debit_account_id.id,
|
||||
'tax_line_id': self.tax_id.id,
|
||||
'tax_line_id': adjustment_type == 'debit' and self.tax_id.id or False,
|
||||
}
|
||||
credit_vals = {
|
||||
'name': self.reason,
|
||||
'debit': 0.0,
|
||||
'credit': self.amount,
|
||||
'credit': abs(self.amount),
|
||||
'account_id': self.credit_account_id.id,
|
||||
'tax_line_id': self.tax_id.id,
|
||||
'tax_line_id': adjustment_type == 'credit' and self.tax_id.id or False,
|
||||
}
|
||||
vals = {
|
||||
'journal_id': self.journal_id.id,
|
||||
@@ -48,6 +50,13 @@ class TaxAdjustments(models.TransientModel):
|
||||
return move.id
|
||||
|
||||
@api.multi
|
||||
def create_move_debit(self):
|
||||
return self.with_context(adjustment_type='debit').create_move()
|
||||
|
||||
@api.multi
|
||||
def create_move_credit(self):
|
||||
return self.with_context(adjustment_type='credit').create_move()
|
||||
|
||||
def create_move(self):
|
||||
#create the adjustment move
|
||||
move_id = self._create_move()
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="amount"/>
|
||||
<field name="adjustment_type"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="tax_id" widget="selection"/>
|
||||
@@ -26,8 +27,14 @@
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="create_move" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
|
||||
<div attrs="{'invisible': [('adjustment_type', '=', 'credit')]}">
|
||||
<button name="create_move_debit" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
|
||||
<button string="Cancel" class="btn btn-default" special="cancel" />
|
||||
</div>
|
||||
<div attrs="{'invisible': [('adjustment_type', '!=', 'credit')]}">
|
||||
<button name="create_move_credit" string="Create and post move" type="object" default_focus="1" class="oe_highlight"/>
|
||||
<button string="Cancel" class="btn btn-default" special="cancel" />
|
||||
</div>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
||||
@@ -419,7 +419,7 @@ class AccountAssetAsset(models.Model):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
asset = super(AccountAssetAsset, self.with_context(mail_create_nolog=True)).create(vals)
|
||||
asset.compute_depreciation_board()
|
||||
asset.sudo().compute_depreciation_board()
|
||||
return asset
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -8,7 +8,7 @@ from odoo.http import request, route
|
||||
|
||||
class PaymentPortal(http.Controller):
|
||||
|
||||
@route('/invoice/pay/<int:invoice_id>/form_tx', type='json', auth="user", website=True)
|
||||
@route('/invoice/pay/<int:invoice_id>/form_tx', type='json', auth="public", website=True)
|
||||
def invoice_pay_form(self, acquirer_id, invoice_id, save_token=False, access_token=None, **kwargs):
|
||||
""" Json method that creates a payment.transaction, used to create a
|
||||
transaction when the user clicks on 'pay now' button on the payment
|
||||
@@ -17,13 +17,11 @@ class PaymentPortal(http.Controller):
|
||||
:return html: form containing all values related to the acquirer to
|
||||
redirect customers to the acquirer website """
|
||||
success_url = kwargs.get('success_url', '/my')
|
||||
callback_method = kwargs.get('callback_method', '')
|
||||
|
||||
invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id)
|
||||
if not invoice_sudo:
|
||||
return False
|
||||
# Check if the current user has access to this invoice
|
||||
commercial_partner_id = request.env.user.partner_id.commercial_partner_id.id
|
||||
if request.env['account.invoice'].sudo().search_count([('id', '=', invoice_id), ('message_partner_ids', 'child_of', commercial_partner_id)]) == 0:
|
||||
return False
|
||||
|
||||
try:
|
||||
acquirer = request.env['payment.acquirer'].browse(int(acquirer_id))
|
||||
@@ -35,7 +33,12 @@ class PaymentPortal(http.Controller):
|
||||
invoice_sudo,
|
||||
acquirer,
|
||||
payment_token=token,
|
||||
tx_type='form_save' if save_token else 'form')
|
||||
tx_type='form_save' if save_token else 'form',
|
||||
add_tx_values={
|
||||
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id,
|
||||
'callback_res_id': invoice_sudo.id,
|
||||
'callback_method': callback_method,
|
||||
})
|
||||
|
||||
# set the transaction id into the session
|
||||
request.session['portal_invoice_%s_transaction_id' % invoice_sudo.id] = tx.id
|
||||
@@ -50,11 +53,12 @@ class PaymentPortal(http.Controller):
|
||||
}
|
||||
)
|
||||
|
||||
@http.route('/invoice/pay/<int:invoice_id>/s2s_token_tx', type='http', auth='user', website=True)
|
||||
@http.route('/invoice/pay/<int:invoice_id>/s2s_token_tx', type='http', auth='public', website=True)
|
||||
def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
|
||||
""" Use a token to perform a s2s transaction """
|
||||
error_url = kwargs.get('error_url', '/my')
|
||||
success_url = kwargs.get('success_url', '/my')
|
||||
callback_method = kwargs.get('callback_method', '')
|
||||
access_token = kwargs.get('access_token')
|
||||
params = {}
|
||||
if access_token:
|
||||
@@ -65,11 +69,6 @@ class PaymentPortal(http.Controller):
|
||||
params['error'] = 'pay_invoice_invalid_doc'
|
||||
return request.redirect(_build_url_w_params(error_url, params))
|
||||
|
||||
# Check if the current user has access to this invoice
|
||||
commercial_partner_id = request.env.user.partner_id.commercial_partner_id.id
|
||||
if request.env['account.invoice'].sudo().search_count([('id', '=', invoice_id), ('message_partner_ids', 'child_of', commercial_partner_id)]) == 0:
|
||||
return False
|
||||
|
||||
try:
|
||||
token = request.env['payment.token'].sudo().browse(int(pm_id))
|
||||
except (ValueError, TypeError):
|
||||
@@ -83,7 +82,12 @@ class PaymentPortal(http.Controller):
|
||||
invoice_sudo,
|
||||
token.acquirer_id,
|
||||
payment_token=token,
|
||||
tx_type='server2server')
|
||||
tx_type='server2server',
|
||||
add_tx_values={
|
||||
'callback_model_id': request.env['ir.model'].sudo().search([('model', '=', invoice_sudo._name)], limit=1).id,
|
||||
'callback_res_id': invoice_sudo.id,
|
||||
'callback_method': callback_method,
|
||||
})
|
||||
|
||||
# set the transaction id into the session
|
||||
request.session['portal_invoice_%s_transaction_id' % invoice_sudo.id] = tx.id
|
||||
|
||||
@@ -497,7 +497,6 @@ class Import(models.TransientModel):
|
||||
'headers_type': header_types or False,
|
||||
'preview': preview,
|
||||
'options': options,
|
||||
'advanced_mode': any([len(models.fix_import_export_id_paths(col)) > 1 for col in headers or []]),
|
||||
'debug': self.user_has_groups('base.group_no_one'),
|
||||
}
|
||||
except Exception as error:
|
||||
|
||||
@@ -307,7 +307,6 @@ var DataImport = Widget.extend(ControlPanelMixin, {
|
||||
this.$buttons.filter('.o_import_button').add(this.$('.oe_import_file_reload'))
|
||||
.prop('disabled', false);
|
||||
this.$el.addClass('oe_import_preview');
|
||||
this.$('input.oe_import_advanced_mode').prop('checked', result.advanced_mode);
|
||||
this.$('.oe_import_grid').html(QWeb.render('ImportView.preview', result));
|
||||
|
||||
if (result.headers.length === 1) {
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
id="oe_import_has_header" checked="checked"/>
|
||||
<label for="oe_import_has_header">The first row
|
||||
contains the label of the column</label>
|
||||
<input type="checkbox" class="oe_import_advanced_mode" disabled="disabled"
|
||||
<input type="checkbox" class="oe_import_advanced_mode" checked="checked"
|
||||
id="oe_import_advanced_mode"/>
|
||||
<label for="oe_import_advanced_mode">Show fields of relation fields (advanced)</label>
|
||||
<p class="oe_import_noheaders">If the file contains
|
||||
|
||||
@@ -258,7 +258,7 @@ class TestPreview(TransactionCase):
|
||||
['qux', '5', '6'],
|
||||
])
|
||||
# Ensure we only have the response fields we expect
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
|
||||
|
||||
@unittest.skipUnless(can_import('xlrd'), "XLRD module not available")
|
||||
def test_xls_success(self):
|
||||
@@ -288,7 +288,7 @@ class TestPreview(TransactionCase):
|
||||
['qux', '5', '6'],
|
||||
])
|
||||
# Ensure we only have the response fields we expect
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
|
||||
|
||||
@unittest.skipUnless(can_import('xlrd.xlsx'), "XLRD/XLSX not available")
|
||||
def test_xlsx_success(self):
|
||||
@@ -318,7 +318,7 @@ class TestPreview(TransactionCase):
|
||||
['qux', '5', '6'],
|
||||
])
|
||||
# Ensure we only have the response fields we expect
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options','advanced_mode', 'debug'])
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
|
||||
|
||||
@unittest.skipUnless(can_import('odf'), "ODFPY not available")
|
||||
def test_ods_success(self):
|
||||
@@ -348,7 +348,7 @@ class TestPreview(TransactionCase):
|
||||
['aux', '5', '6'],
|
||||
])
|
||||
# Ensure we only have the response fields we expect
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
|
||||
self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
|
||||
|
||||
|
||||
class test_convert_import_data(TransactionCase):
|
||||
|
||||
@@ -141,6 +141,31 @@ FormRenderer.include({
|
||||
this._super.apply(this, arguments);
|
||||
this.noContentHelp = params.noContentHelp;
|
||||
this.actionsDescr = {};
|
||||
this._boardSubcontrollers = []; // for board: controllers of subviews
|
||||
},
|
||||
/**
|
||||
* Call `on_attach_callback` for each subview
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
on_attach_callback: function () {
|
||||
_.each(this._boardSubcontrollers, function (controller) {
|
||||
if ('on_attach_callback' in controller) {
|
||||
controller.on_attach_callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Call `on_detach_callback` for each subview
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
on_detach_callback: function () {
|
||||
_.each(this._boardSubcontrollers, function (controller) {
|
||||
if ('on_detach_callback' in controller) {
|
||||
controller.on_detach_callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -243,6 +268,7 @@ FormRenderer.include({
|
||||
hasSelectors: false,
|
||||
});
|
||||
return view.getController(self).then(function (controller) {
|
||||
self._boardSubcontrollers.push(controller);
|
||||
return controller.appendTo(params.$node);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ odoo.define('board.dashboard_tests', function (require) {
|
||||
|
||||
var testUtils = require('web.test_utils');
|
||||
var FormView = require('web.FormView');
|
||||
var ListRenderer = require('web.ListRenderer');
|
||||
|
||||
var createView = testUtils.createView;
|
||||
|
||||
@@ -454,5 +455,48 @@ QUnit.test('clicking on a kanban\'s button should trigger the action', function
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('subviews are aware of attach in or detach from the DOM', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
// patch list renderer `on_attach_callback` for the test only
|
||||
testUtils.patch(ListRenderer, {
|
||||
on_attach_callback: function () {
|
||||
assert.step('subview on_attach_callback');
|
||||
}
|
||||
});
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'board',
|
||||
data: this.data,
|
||||
arch: '<form string="My Dashboard">' +
|
||||
'<board style="2-1">' +
|
||||
'<column>' +
|
||||
'<action context="{}" view_mode="list" string="ABC" name="51" domain="[]"></action>' +
|
||||
'</column>' +
|
||||
'</board>' +
|
||||
'</form>',
|
||||
mockRPC: function (route) {
|
||||
if (route === '/web/action/load') {
|
||||
return $.when({
|
||||
res_model: 'partner',
|
||||
views: [[4, 'list']],
|
||||
});
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
archs: {
|
||||
'partner,4,list':
|
||||
'<list string="Partner"><field name="foo"/></list>',
|
||||
},
|
||||
});
|
||||
|
||||
assert.verifySteps(['subview on_attach_callback']);
|
||||
|
||||
// restore on_attach_callback of ListRenderer
|
||||
testUtils.unpatch(ListRenderer);
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
<label for="cal_client_secret" string="Client Secret" class="col-xs-3 col-md-3 o_light_label"/>
|
||||
<field name="cal_client_secret" password="True" nolabel="1"/>
|
||||
</div>
|
||||
<a href="https://www.odoo.com/documentation/user/online/crm/calendar/google_calendar_credentials.html" class="oe-link" target="_blank"><i class="fa fa-fw fa-arrow-right"/>Tutorial</a>
|
||||
<a href="https://www.odoo.com/documentation/user/11.0/crm/optimize/google_calendar_credentials.html" class="oe-link" target="_blank"><i class="fa fa-fw fa-arrow-right"/>Tutorial</a>
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<field name="context">{'module' : 'general_settings'}</field>
|
||||
<menuitem id="menu_calendar_google_tech_config"
|
||||
name="API Credentials"
|
||||
parent="calendar.menu_calendar_configuration"
|
||||
|
||||
@@ -41,6 +41,13 @@ class AccountAnalyticLine(models.Model):
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
# compute employee only for timesheet lines, makes no sense for other lines
|
||||
if not vals.get('employee_id') and vals.get('project_id'):
|
||||
if vals.get('user_id'):
|
||||
ts_user_id = vals['user_id']
|
||||
else:
|
||||
ts_user_id = self._default_user()
|
||||
vals['employee_id'] = self.env['hr.employee'].search([('user_id', '=', ts_user_id)], limit=1).id
|
||||
vals = self._timesheet_preprocess(vals)
|
||||
return super(AccountAnalyticLine, self).create(vals)
|
||||
|
||||
@@ -62,13 +69,6 @@ class AccountAnalyticLine(models.Model):
|
||||
if vals.get('employee_id') and not vals.get('user_id'):
|
||||
employee = self.env['hr.employee'].browse(vals['employee_id'])
|
||||
vals['user_id'] = employee.user_id.id
|
||||
# compute employee only for timesheet lines, makes no sense for other lines
|
||||
if not vals.get('employee_id') and vals.get('project_id'):
|
||||
if vals.get('user_id'):
|
||||
ts_user_id = vals['user_id']
|
||||
else:
|
||||
ts_user_id = self._default_user()
|
||||
vals['employee_id'] = self.env['hr.employee'].search([('user_id', '=', ts_user_id)], limit=1).id
|
||||
# force customer partner, from the task or the project
|
||||
if (vals.get('project_id') or vals.get('task_id')) and not vals.get('partner_id'):
|
||||
partner_id = False
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<span t-field="l.user_id.partner_id.name"/>
|
||||
</td>
|
||||
<td >
|
||||
<span t-field="l.name"/>
|
||||
<span t-field="l.name" t-options="{'widget': 'text'}"/>
|
||||
</td>
|
||||
<td t-if="show_task or show_project">
|
||||
<t t-if="show_project"><span t-field="l.project_id.name"/></t>
|
||||
@@ -72,4 +72,4 @@
|
||||
name="hr_timesheet.report_timesheet"
|
||||
file="report_timesheet"
|
||||
/>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import controllers
|
||||
from . import models
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import main
|
||||
@@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import odoo
|
||||
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
from odoo.osv import expression
|
||||
from odoo.addons.web.controllers.main import WebClient, Home
|
||||
|
||||
class Routing(Home):
|
||||
|
||||
@http.route('/website/translations', type='json', auth="public", website=True)
|
||||
def get_website_translations(self, lang, mods=None):
|
||||
Modules = request.env['ir.module.module'].sudo()
|
||||
IrHttp = request.env['ir.http'].sudo()
|
||||
domain = IrHttp._get_translation_frontend_modules_domain()
|
||||
modules = Modules.search(
|
||||
expression.AND([domain, [('state', '=', 'installed')]])
|
||||
).mapped('name')
|
||||
if mods:
|
||||
modules += mods
|
||||
return WebClient().translations(mods=modules, lang=lang)
|
||||
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import os.path
|
||||
|
||||
try:
|
||||
import GeoIP # Legacy
|
||||
except ImportError:
|
||||
GeoIP = None
|
||||
|
||||
try:
|
||||
import geoip2
|
||||
import geoip2.database
|
||||
except ImportError:
|
||||
geoip2 = None
|
||||
|
||||
class GeoIPResolver(object):
|
||||
def __init__(self, fname):
|
||||
self.fname = fname
|
||||
try:
|
||||
self._db = geoip2.database.Reader(fname)
|
||||
self.version = 2
|
||||
except Exception:
|
||||
try:
|
||||
self._db = GeoIP.open(fname, GeoIP.GEOIP_STANDARD)
|
||||
self.version = 1
|
||||
assert self._db.database_info is not None
|
||||
except Exception:
|
||||
raise ValueError('Invalid GeoIP database: %r' % fname)
|
||||
|
||||
def __del__(self):
|
||||
if self.version == 2:
|
||||
self._db.close()
|
||||
|
||||
@classmethod
|
||||
def open(cls, fname):
|
||||
if not GeoIP and not geoip2:
|
||||
return None
|
||||
if not os.path.exists(fname):
|
||||
return None
|
||||
return GeoIPResolver(fname)
|
||||
|
||||
def resolve(self, ip):
|
||||
if self.version == 1:
|
||||
return self._db.record_by_addr(ip) or {}
|
||||
elif self.version == 2:
|
||||
try:
|
||||
r = self._db.city(ip)
|
||||
except (ValueError, geoip2.errors.AddressNotFoundError):
|
||||
return {}
|
||||
return {
|
||||
'city': r.city.name,
|
||||
'country_code': r.country.iso_code,
|
||||
'country_name': r.country.name,
|
||||
'region': r.subdivisions[0].iso_code if r.subdivisions else None,
|
||||
'time_zone': r.location.time_zone,
|
||||
}
|
||||
|
||||
# compat
|
||||
def record_by_addr(self, addr):
|
||||
return self.resolve(addr)
|
||||
@@ -18,6 +18,8 @@ from odoo.addons.base.models.ir_http import RequestUID, ModelConverter
|
||||
from odoo.http import request
|
||||
from odoo.tools import config, ustr, pycompat
|
||||
|
||||
from ..geoipresolver import GeoIPResolver
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# global resolver (GeoIP API is thread-safe, for multithreaded workers)
|
||||
@@ -229,6 +231,13 @@ class IrHttp(models.AbstractModel):
|
||||
return request.env['res.lang'].search([('code', '=', lang_code)], limit=1)
|
||||
return request.env['res.lang'].search([], limit=1)
|
||||
|
||||
@classmethod
|
||||
def _get_translation_frontend_modules_domain(cls):
|
||||
""" Return a domain to list the domain adding web-translations and
|
||||
dynamic resources that may be used frontend views
|
||||
"""
|
||||
return []
|
||||
|
||||
bots = "bot|crawl|slurp|spider|curl|wget|facebookexternalhit".split("|")
|
||||
|
||||
@classmethod
|
||||
@@ -258,25 +267,18 @@ class IrHttp(models.AbstractModel):
|
||||
# Lazy init of GeoIP resolver
|
||||
if odoo._geoip_resolver is not None:
|
||||
return
|
||||
geofile = config.get('geoip_database')
|
||||
try:
|
||||
import GeoIP
|
||||
# updated database can be downloaded on MaxMind website
|
||||
# http://dev.maxmind.com/geoip/legacy/install/city/
|
||||
geofile = config.get('geoip_database')
|
||||
if os.path.exists(geofile):
|
||||
odoo._geoip_resolver = GeoIP.open(geofile, GeoIP.GEOIP_STANDARD)
|
||||
else:
|
||||
odoo._geoip_resolver = False
|
||||
_logger.warning('GeoIP database file %r does not exists, apt-get install geoip-database-contrib or download it from http://dev.maxmind.com/geoip/legacy/install/city/', geofile)
|
||||
except ImportError:
|
||||
odoo._geoip_resolver = False
|
||||
odoo._geoip_resolver = GeoIPResolver.open(geofile) or False
|
||||
except Exception as e:
|
||||
_logger.warning('Cannot load GeoIP: %s', ustr(e))
|
||||
|
||||
@classmethod
|
||||
def _geoip_resolve(cls):
|
||||
if 'geoip' not in request.session:
|
||||
record = {}
|
||||
if odoo._geoip_resolver and request.httprequest.remote_addr:
|
||||
record = odoo._geoip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
|
||||
record = odoo._geoip_resolver.resolve(request.httprequest.remote_addr) or {}
|
||||
request.session['geoip'] = record
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<field name="cash_account_code_prefix">100</field>
|
||||
<field name="currency_id" ref="base.CHF"/>
|
||||
<field name="transfer_account_id" ref="transfer_account_id"/>
|
||||
<field name="spoken_languages" eval="'it_IT;de_CH'"/>
|
||||
<field name="spoken_languages" eval="'it_IT;de_DE;de_CH'"/>
|
||||
</record>
|
||||
<record id="transfer_account_id" model="account.account.template">
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,66 +6,71 @@ do_niif_11020200,11020200,Operaciones en Bolsa,account.data_account_type_current
|
||||
do_niif_11020300,11020300,Otros Valores Negociables,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1102"
|
||||
do_niif_11030101,11030101,Cheques Devueltos por Cobrar,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110301"
|
||||
do_niif_11030102,11030102,Intereses por Cobrar,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110301"
|
||||
do_niif_11030201,11030201,Cuenta por Cobrar a Clientes,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030202,11030202,Cuenta por Cobrar a Funcionarios y Empleados,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030203,11030203,Cuenta por Cobrar a Afiliadas,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030204,11030204,Cuenta por Cobrar a Accionistas,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030201,11030201,Cuentas por Cobrar a Clientes,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030202,11030202,Cuentas por Cobrar a Funcionarios y Empleados,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030203,11030203,Cuentas por Cobrar a Afiliadas,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030204,11030204,Cuentas por Cobrar a Accionistas,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11030205,11030205,Otras Cuentas por Cobrar,account.data_account_type_receivable,TRUE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1103,account_tag_110302"
|
||||
do_niif_11040100,11040100,Provisión Incobrables a Clientes,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040200,11040200,Provisión Incobrables a Funcionarios y Empleados,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040300,11040300,Provisión Incobrables a Afiliadas,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040400,11040400,Provisión Incobrables a Accionistas,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040500,11040500,Provisión Otras Cuentas Incobrables,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040100,11040100,Provisiones de Incobrables a Clientes,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040200,11040200,Provisiones de Incobrables a Funcionarios y Empleados,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040300,11040300,Provisiones de Incobrables a Afiliadas,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040400,11040400,Provisiones de Incobrables a Accionistas,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11040500,11040500,Provisiones de Otras Cuentas Incobrables,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1104"
|
||||
do_niif_11050100,11050100,Inventario de Mercancías o Productos Terminados,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050200,11050200,Inventario de Materia Prima,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050300,11050300,Inventario en Tránsito,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050400,11050400,Materiales y Suministros en Inventario,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050500,11050500,Combustibles en Inventario,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050400,11050400,Inventario de Materiales y Suministros,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050500,11050500,Inventario de Combustibles,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11050600,11050600,Bienes Enviados No Facturados,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1105"
|
||||
do_niif_11060100,11060100,Deterioro Acum. de Inventario en Almacen,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1106"
|
||||
do_niif_11060200,11060200,Deterioro Acum. de Materiales y Suministros,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1106"
|
||||
do_niif_11060300,11060300,Deterioro Acum. de Combustibles,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1106"
|
||||
do_niif_11070100,11070100,Obsolescencia Inventario en Almacen,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11070200,11070200,Obsolescencia Materiales y Suministros,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11070300,11070300,Obsolescencia Combustibles,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11080101,11080101,ITBIS Pagado en Compras Locales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080102,11080102,ITBIS Pagado en Servicios Locales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080103,11080103,ITBIS Pagado por Importaciones,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080301,11080301,ITBIS Pagado en Ventas con Tarjeta de Crédito (Norma 08-04),account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11080302,11080302,Saldo a Favor ITBIS,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11080303,11080303,Saldo a Favor ISR,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11070100,11070100,Obsolescencia de Inventario en Almacen,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11070200,11070200,Obsolescencia de Materiales y Suministros,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11070300,11070300,Obsolescencia de Combustibles,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1107"
|
||||
do_niif_11080101,11080101,ITBIS Pagado en Compras de Bienes Locales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080102,11080102,ITBIS Pagado en Compras de Servicios Deducibles,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080103,11080103,ITBIS Pagado en Importaciones,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080104,11080104,ITBIS en Compras de Bienes o Servicios Sujetos a Proporcionalidad,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080105,11080105,ITBIS en Importaciones Sujeto a Proporcionalidad,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080106,11080106,ITBIS Pagado en Importaciones Sujeto a Proporcionalidad,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110801"
|
||||
do_niif_11080301,11080301,ITBIS Retenido por Ventas (N08-04 y N02-05),account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11080302,11080302,ITBIS Retenido por Entidades del Estado (5%),account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11080303,11080303,Saldo a Favor Anterior,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1108,account_tag_110803"
|
||||
do_niif_11090100,11090100,Acciones Temporales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1109"
|
||||
do_niif_11090200,11090200,Depósitos a Plazo Temporales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1109"
|
||||
do_niif_11090300,11090300,Bonos Temporales,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1109"
|
||||
do_niif_11090400,11090400,Fianzas y Depósitos,account.data_account_type_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1109"
|
||||
do_niif_11100100,11100100,Gastos Pagados por Anticipado,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100200,11100200,Renta Pagada por Anticipado,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100300,11100300,Seguros Pagados por Anticipado,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100400,11100400,Anticipos ISR,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100500,11100500,Anticipos Gastos,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100600,11100600,Anticipos 1% Activos,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100100,11100100,Avance a Proveedores,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100200,11100200,Alquileres pagados por Anticipado,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100300,11100300,Anticipos para Seguros,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100400,11100400,Anticipos para ISR,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100500,11100500,Anticipos para Gastos,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_11100600,11100600,Anticipos para 1% Activos,account.data_account_type_prepayments,FALSE,do_chart_template,"account_tag_1,account_tag_11,account_tag_1110"
|
||||
do_niif_12010101,12010101,Terrenos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120101"
|
||||
do_niif_12010102,12010102,Edificaciones,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120101"
|
||||
do_niif_12010103,12010103,Mejoras en Edificaciones,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120101"
|
||||
do_niif_12010201,12010201,Equipo de Transporte,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120102"
|
||||
do_niif_12010202,12010202,Mobiliario y Equipos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120102"
|
||||
do_niif_12010301,12010301,Maquinaria,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010104,12010104,Mejoras en Edificaciones y Locales Arrendados,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120101"
|
||||
do_niif_12010201,12010201,Equipos de Transporte Liviano,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120102"
|
||||
do_niif_12010202,12010202,Mobiliarios y Equipos de Oficina,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120102"
|
||||
do_niif_12010301,12010301,Maquinarias,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010302,12010302,Herramientas,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010303,12010303,Instalaciones,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010304,12010304,Misceláneos u otros activos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010304,12010304,Sistemas de Cámara y Seguridad,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12010305,12010305,Misceláneos u otros activos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1201,account_tag_120103"
|
||||
do_niif_12020100,12020100,Depreciación Acum. de Edificios,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020200,12020200,Depreciación Acum. de Equipo de Transporte,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020300,12020300,Depreciación Acum. de Mobiliario y Equipos,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020400,12020400,Depreciación Acum. de Maquinaria,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020200,12020200,Depreciación Acum. de Equipos de Transporte,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020300,12020300,Depreciación Acum. de Mobiliarios y Equipos,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020400,12020400,Depreciación Acum. de Maquinarias,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020500,12020500,Depreciación Acum. de Herramientas,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12020600,12020600,Depreciación Acum. de Instalaciones,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1202"
|
||||
do_niif_12040100,12040100,Marcas y Patentes,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1204"
|
||||
do_niif_12040200,12040200,Programas Informáticos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1204"
|
||||
do_niif_12050100,12050100,Edificios y Locales Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12050200,12050200,Maquinaria y Equipo Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12050300,12050300,Instalaciones Arrendadas,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12060100,12060100,Depreciación Acum. Edificios y Locales Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1206"
|
||||
do_niif_12060200,12060200,Depreciación Acum. Maquinaria y Equipo Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1206"
|
||||
do_niif_12040200,12040200,Licencias y Programas Informáticos,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1204"
|
||||
do_niif_12050100,12050100,Edificaciones y Locales Arrendados,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12050200,12050200,Maquinarias y Equipos Arrendados,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12050300,12050300,Instalaciones Arrendadas,account.data_account_type_fixed_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1205"
|
||||
do_niif_12060100,12060100,Depreciación Acum. Edificaciones y Locales Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1206"
|
||||
do_niif_12060200,12060200,Depreciación Acum. Maquinarias y Equipos Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1206"
|
||||
do_niif_12060300,12060300,Depreciación Acum. Instalaciones Arrendadas,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1206"
|
||||
do_niif_12070100,12070100,Deterioro Valor Acum. Edificios y Locales Arrendados,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1207"
|
||||
do_niif_12070200,12070200,Deterioro Valor Acum. Maquinaria y Equipo Arrendado,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1207"
|
||||
@@ -74,11 +79,12 @@ do_niif_12080100,12080100,Acciones en otras sociedades,account.data_account_type
|
||||
do_niif_12090100,12090100,Diferencias temporales deducibles,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1209"
|
||||
do_niif_12090200,12090200,Gastos Organizacionales Diferidos,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1209"
|
||||
do_niif_12090300,12090300,ISR Deducible,account.data_account_type_non_current_assets,FALSE,do_chart_template,"account_tag_1,account_tag_12,account_tag_1209"
|
||||
do_niif_13010100,13010101,Costos de Construcción en Proceso,account.data_account_type_non_current_assets,FALSE,do_chart_template,
|
||||
do_niif_21010100,21010100,Préstamos Bancarios por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010200,21010200,Cuenta por Pagar Proveedores Locales,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010300,21010300,Cuenta por Pagar Proveedores del Exterior,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010400,21010400,Cuenta por Pagar a Afiliadas,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010500,21010500,Cuenta por Pagar a Accionistas,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010200,21010200,Cuentas por Pagar a Proveedores Locales,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010300,21010300,Cuentas por Pagar a Proveedores del Exterior,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010400,21010400,Cuentas por Pagar a Afiliadas,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010500,21010500,Cuentas por Pagar a Accionistas,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010600,21010600,Nóminas por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010700,21010700,Intereses por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
do_niif_21010800,21010800,Otras Cuentas por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2101"
|
||||
@@ -91,48 +97,48 @@ do_niif_21020600,21020600,Seguro Médico por Pagar,account.data_account_type_non
|
||||
do_niif_21020700,21020700,Seguro Familiar de Salud (SFS) por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21020800,21020800,Aporte a Fondo de Pensiones (AFP) por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21020900,21020900,Seguro de Riesgo Laboral (SRL) por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021000,21021000,INFOTEP por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021100,21021100,Otras Remuneraciones por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021200,21021200,Bienes Recibidos no Pagados,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021000,21021000,INFOTEP por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021100,21021100,Tesorería de la Seguridad Social (TSS) por Pagar,account.data_account_type_payable,TRUE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21021200,21021200,Bienes Recibidos no Facturados,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2102"
|
||||
do_niif_21030101,21030101,ITBIS por Venta Servicios,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210301"
|
||||
do_niif_21030102,21030102,ITBIS por Venta Bienes,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210301"
|
||||
do_niif_21030103,21030103,ITBIS por Venta Bienes - al Exterior,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210301"
|
||||
do_niif_21030201,21030201,ITBIS Retenido Persona Jurídica (N 02-05),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030202,21030202,ITBIS Retenido Persona Física (R 293-11),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030203,21030203,ITBIS Retenido a Entidades No Lucrativas (N 01-2011),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030204,21030204,ITBIS Retenido por Servicios Profesionales Liberales (N 02-05),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030205,21030205,ITBIS Retenido a Proveedores Informales de Bienes (N 08-10),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030103,21030103,ITBIS por Venta Servicios en Nombre de Terceros,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210301"
|
||||
do_niif_21030201,21030201,ITBIS Retenido a Persona Jurídica (N02-05),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030202,21030202,ITBIS Retenido a Persona Física (R293-11),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030203,21030203,ITBIS Retenido a Entidades No Lucrativas (N01-11),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030204,21030204,ITBIS Retenido por Servicios Profesionales (N02-05),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030205,21030205,ITBIS Retenido a Informales de Bienes (N08-10),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210302"
|
||||
do_niif_21030301,21030301,ISR Retenido por Honorarios Profesionales de Personas Físicas,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030302,21030302,ISR Retenido por Alquileres Pagados a Personas Físicas,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030303,21030303,ISR Retenido por Dividendos Pagados,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030304,21030304,ISR Retenido por Intereses Pagados al Exterior,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030305,21030305,ISR Retenido por Intereses Pagados,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030306,21030306,ISR Retenido por Transferencias de Títulos y Propiedades,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030307,21030307,ISR Retenido por Remesas al Exterior (Ley 253-12),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030308,21030308,Otras Retenciones (N 07-07),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030307,21030307,ISR Retenido por Remesas al Exterior (L253-12),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030308,21030308,Otras Retenciones (N07-07),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030309,21030309,Otras Retenciones,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210303"
|
||||
do_niif_21030401,21030401,Impuesto al Salario (ISR),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210304"
|
||||
do_niif_21030401,21030401,Retención de Impuesto al Salario (ISR del IR3),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210304"
|
||||
do_niif_21030402,21030402,Retención de Seguro Familiar de Salud (SFS),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210304"
|
||||
do_niif_21030403,21030403,Retención de Fondo de Pensiones (AFP),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210304"
|
||||
do_niif_21030404,21030404,Retención de INFOTEP (0.5%),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210304"
|
||||
do_niif_21030501,21030501,ISR por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210305"
|
||||
do_niif_21030502,21030502,Anticipos ISR por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210305"
|
||||
do_niif_21030503,21030503,Propina por Pagar (Ley 16-92),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210305"
|
||||
do_niif_21030503,21030503,Propina Legal por Pagar (L16-92),account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210305"
|
||||
do_niif_21030504,21030504,Otros Impuestos por Pagar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2103,account_tag_210305"
|
||||
do_niif_21040100,21040100,Provisión Pago Alquileres,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21040200,21040200,Provisión Arrendamiento Financiero,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21040300,21040300,Provisión Gastos Fijos,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21040100,21040100,Provisiones Pago Alquileres,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21040200,21040200,Provisiones Arrendamiento Financiero,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21040300,21040300,Provisiones Gastos Fijos,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2104"
|
||||
do_niif_21050100,21050100,Tarjeta de Crédito Empresarial,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2105"
|
||||
do_niif_21050200,21050200,Prima de Tarjetas de Crédito,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_21,account_tag_2105"
|
||||
do_niif_22010100,22010100,Préstamos Bancarios Largo Plazo,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2201"
|
||||
do_niif_22010200,22010200,Préstamos Hipotecarios LP,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2201"
|
||||
do_niif_22012300,22012300,Préstamos Accionistas / Particulares,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2201"
|
||||
do_niif_22020100,22020100,Provisión Beneficios de Empleados LP,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22020200,22020200,Provisión Prestaciones Laborales,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22020300,22020300,Provisión Indemnizaciones,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22030100,22030100,Anticipos de Clientes,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2203"
|
||||
do_niif_22030200,22030200,Garantías de Clientes,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2203"
|
||||
do_niif_22040100,22040100,Provisión Arrendamiento Financiero LP,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2204"
|
||||
do_niif_22020100,22020100,Provisiones Beneficios de Empleados LP,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22020200,22020200,Provisiones Prestaciones Laborales,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22020300,22020300,Provisiones Indemnizaciones,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2202"
|
||||
do_niif_22030100,22030100,Anticipos o Garantías de Clientes,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2203"
|
||||
do_niif_22030200,22030200,Depósitos por Identificar,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2203"
|
||||
do_niif_22040100,22040100,Provisiones Arrendamiento Financiero LP,account.data_account_type_non_current_liabilities,FALSE,do_chart_template,"account_tag_2,account_tag_22,account_tag_2204"
|
||||
do_niif_31010100,31010100,Capital Social Autorizado,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_31,account_tag_3101"
|
||||
do_niif_31010200,31010200,Capital Social en Acciones no Emitidas,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_31,account_tag_3101"
|
||||
do_niif_31010300,31010300,Capital Social Pagado,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_31,account_tag_3101"
|
||||
@@ -149,123 +155,127 @@ do_niif_33020100,33020100,Utilidad del Ejercicio,account.data_account_type_equit
|
||||
do_niif_33020200,33020200,Pérdidas del Ejercicio,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_33,account_tag_3302"
|
||||
do_niif_33040100,33040100,Superávit en Reserva,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_33,account_tag_3304"
|
||||
do_niif_33040200,33040200,Déficit en Reserva,account.data_account_type_equity,FALSE,do_chart_template,"account_tag_3,account_tag_33,account_tag_3304"
|
||||
do_niif_41010100,41010100,Ventas Bienes,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4101"
|
||||
do_niif_41010200,41010200,Ventas Bienes - Al Exterior,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4101"
|
||||
do_niif_41020100,41020100,Ventas Servicios,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4102"
|
||||
do_niif_41020200,41020200,Ventas Servicios - Al Exterior,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4102"
|
||||
do_niif_41010100,41010100,Ventas de Bienes,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4101"
|
||||
do_niif_41010200,41010200,Ventas por Exportaciones de Bienes,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4101"
|
||||
do_niif_41020100,41020100,Ventas de Servicios,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4102"
|
||||
do_niif_41020200,41020200,Ventas por Exportaciones de Servicios,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4102"
|
||||
do_niif_41030100,41030100,Devoluciones de Bienes,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4103"
|
||||
do_niif_41030200,41030200,Devoluciones por Servicios,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4103"
|
||||
do_niif_41040100,41040100,Descuentos por Ventas (por NC),account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_41,account_tag_4104"
|
||||
do_niif_42010100,42010100,Intereses sobre Certificados,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4201"
|
||||
do_niif_42010200,42010200,Intereses en Cuentas Bancarias,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4201"
|
||||
do_niif_42010200,42010200,Intereses por Cuentas Bancarias,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4201"
|
||||
do_niif_42010300,42010300,Intereses por Financiamientos,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4201"
|
||||
do_niif_42020100,42020100,Ingresos por Ventas de Activos,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4202"
|
||||
do_niif_42020100,42020100,Ingresos por Ventas de Activos Depreciables (CAT II y III) ,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4202"
|
||||
do_niif_42030100,42030100,Ingresos por Dividendos Ganados,account.data_account_type_revenue,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4203"
|
||||
do_niif_42040100,42040100,Ingresos por Diferencia Cambiaria,account.data_account_type_other_income,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4204"
|
||||
do_niif_42040200,42040200,Cobro de Cuentas Incobrables,account.data_account_type_other_income,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4204"
|
||||
do_niif_42040300,42040300,Otros Ingresos,account.data_account_type_other_income,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4204"
|
||||
do_niif_42040300,42040300,Ingresos por Sobrante en Caja,account.data_account_type_other_income,FALSE,do_chart_template,"account_tag_4,account_tag_42,account_tag_4204"
|
||||
do_niif_51010100,51010100,Costos de Bienes,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5101"
|
||||
do_niif_51010200,51010200,Costos de Servicios,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5101"
|
||||
do_niif_51010300,51010300,Diferencia de Precio,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5101"
|
||||
do_niif_51010300,51010300,Diferencia en Precio,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5101"
|
||||
do_niif_51020400,51020400,Costos de Importación,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5102"
|
||||
do_niif_51010500,51010500,ITBIS llevado al Costo,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5101"
|
||||
do_niif_51020100,51020100,Costos de Materia Prima,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5102"
|
||||
do_niif_51020200,51020200,Costos de Mano de Obra,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5102"
|
||||
do_niif_51020300,51020300,Costos Indirectos,account.data_account_type_direct_costs,FALSE,do_chart_template,"account_tag_5,account_tag_51,account_tag_5102"
|
||||
do_niif_52010100,52010100,Sueldos y Salarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010200,52010200,Regalía Pascual,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010300,52010300,Retribuciones Complementarias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010400,52010400,Bono Vacacional,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010500,52010500,Bono por Desempeño,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010600,52010600,Comisiones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010700,52010700,Indemnizaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010800,52010800,Bonificaciones y Gratificaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010900,52010900,Dietas al Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52011000,52011000,Cursos y Entrenamientos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52011100,52011100,Prestaciones Laborales (Preaviso y Cesantia),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52011200,52011200,Incentivos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52011300,52011300,Horas Extras,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52011400,52011400,Otros Gastos de Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201"
|
||||
do_niif_52010102,52010102,Contribución a la Administradora de Fondos de Pensiones (AFP),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010103,52010103,Contribución al Seguro Riesgo Laboral (SRL),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010104,52010104,Contribución al Seguro Familiar de Salud (SFS),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010201,52010201,Contribución a la Administradora de Riesgos de Salud (ARS),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010202,52010202,Contribución a Seguros del Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010203,52010203,Contribución a Planes Complementarios de Salud,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010204,52010204,Contribución Seguros de Vida,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010205,52010205,Contribución al INFOTEP,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52020100,52020100,Energía Eléctrica,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020200,52020200,Comunicaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020300,52020300,Papelería y útiles,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020400,52020400,Útiles de Aseo y Limpieza,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020500,52020500,Agua y Basura,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020600,52020600,Seguro de Edificio,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020700,52020700,Combustibles y Lubricantes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020800,52020800,Alquileres,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52020900,52020900,Franquicias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021000,52021000,Eventos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021100,52021100,Seguros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021200,52021200,Servicios de Mensajería,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021300,52021300,Flete y Carga,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021400,52021400,Cuotas y Suscripciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52021500,52021500,Otros Gastos de Administración,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5202"
|
||||
do_niif_52030101,52030101,Legales (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030102,52030102,Contabilidad y Auditoría (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030103,52030103,Tecnología (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030104,52030104,Mantenimiento de Planta (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030105,52030105,Mantenimiento del Local (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030106,52030106,Mantenimiento Mobiliario y Equipos (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030107,52030107,Asesorías (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030108,52030108,Fumigaciones (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030109,52030109,Copias y Escaneos (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030110,52030110,Servicios de Vigilancia (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030111,52030111,Otros Servicios Profesionales (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030201,52030201,Legales (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030202,52030202,Contabilidad y Auditoría (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030203,52030203,Tecnología (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030204,52030204,Mantenimiento de Planta (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030205,52030205,Mantenimiento del Local (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030206,52030206,Mantenimiento Mobiliario y Equipos (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030207,52030207,Asesorías (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030208,52030208,Fumigaciones (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030209,52030209,Copias y Escaneos (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030210,52030210,Servicios de Vigilancia (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030211,52030211,Otros Servicios Profesionales (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030301,52030301,Honorarios por Servicios del Exterior - Relacionadas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520303"
|
||||
do_niif_52030302,52030302,Honorarios por Servicios del Exterior - Terceros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5203,account_tag_520303"
|
||||
do_niif_52040100,52040100,Gastos por Depreciación de Edificios,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52040200,52040200,Gastos por Depreciación de Equipo de Transporte,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52040300,52040300,Gastos por Depreciación de Mobiliario y Equipos,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52040400,52040400,Gastos por Depreciación de Maquinaria,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52040500,52040500,Gastos por Depreciación de Herramientas,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52040600,52040600,Gastos por Depreciación de Instalaciones,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5204"
|
||||
do_niif_52050100,52050100,Gastos por Reparación de Edificios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52050200,52050200,Gastos por Reparación de Equipo de Transporte,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52050300,52050300,Gastos por Reparación de Mobiliario y Equipos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52050400,52050400,Gastos por Reparación de Maquinaria,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52050500,52050500,Gastos por Reparación de Herramientas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52050600,52050600,Gastos por Reparación de Instalaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5205"
|
||||
do_niif_52060100,52060100,Relaciones Públicas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060200,52060200,Publicidad,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060300,52060300,Viajes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060400,52060400,Donaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060500,52060500,Donaciones a ProIndustria (Ley 392-07),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060600,52060600,Promociones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52060700,52060700,Otros Gastos de Representación,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5206"
|
||||
do_niif_52070100,52070100,Gastos por Préstamos Financieros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070200,52070200,Retención por Cheques y Transferencias Electrónicas (0.15%),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070300,52070300,Intereses Bancarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070400,52070400,Comisiones Bancarias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070500,52070500,Comisión de Tarjeta de Crédito,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070600,52070600,Nota de Cargos por Banco,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070700,52070700,Seguro sobre Préstamos Bancarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070800,52070800,Pérdidas por Diferencia Cambiaria,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52070900,52070900,Otro Gastos Financieros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5207"
|
||||
do_niif_52080100,52080100,Gastos por Siniestros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080200,52080200,Pérdidas por Ventas de Activos Fijos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080300,52080300,Pérdidas por Cuentas Incobrables,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080400,52080400,Gastos por ISR,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080500,52080500,Impuestos a los Activos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080600,52080600,Penalidades/Recargos de DGII,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080700,52080700,Penalidades/Recargos de TSS,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080800,52080800,Gastos Sin Comprobante,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_52080900,52080900,Gastos por Impuestos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_5,account_tag_52,account_tag_5208"
|
||||
do_niif_61010100,61010100,Pérdidas y Ganancias,account.data_unaffected_earnings,FALSE,do_chart_template,"account_tag_6,account_tag_61,account_tag_6101"
|
||||
do_niif_52010100,61010100,Sueldos y Salarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010200,61010200,Regalía Pascual,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010300,61010300,Retribuciones Complementarias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010400,61010400,Bono Vacacional,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010500,61010500,Bono por Desempeño,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010600,61010600,Comisiones a Empleados,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010700,61010700,Indemnizaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010800,61010800,Bonificaciones y Gratificaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010900,61010900,Comidas o Dietas al Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011000,61011000,Cursos y Entrenamientos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011100,61011100,Prestaciones Laborales (Preaviso y Cesantia),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011200,61011200,Incentivos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011300,61011300,Horas Extras,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011400,61011400,Uniformes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52011500,61011500,Otros Gastos de Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201"
|
||||
do_niif_52010102,61010102,Contribución a la Administradora de Fondos de Pensiones (AFP),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010103,61010103,Contribución al Seguro Riesgo Laboral (SRL),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010104,61010104,Contribución al Seguro Familiar de Salud (SFS),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520101"
|
||||
do_niif_52010201,61010201,Contribución a la Administradora de Riesgos de Salud (ARS),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010202,61010202,Contribución a Seguros del Personal,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010203,61010203,Contribución a Planes Complementarios de Salud,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010204,61010204,Contribución Seguros de Vida,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52010205,61010205,Contribución al INFOTEP,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5201,account_tag_520102"
|
||||
do_niif_52020100,61020100,Energía Eléctrica,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020200,61020200,Comunicaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020300,61020300,Suministros de Oficina (Papelería y útiles),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020400,61020400,Útiles de Aseo y Limpieza,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020500,61020500,Agua y Basura,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020600,61020600,Seguro de Edificio y Locales,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020700,61020700,Combustibles y Lubricantes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020800,61020800,Alquileres / Arrendamientos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52020900,61020900,Franquicias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021000,61021000,Eventos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021100,61021100,Seguros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021200,61021200,Servicios de Mensajería,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021300,61021300,Flete y Carga,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021400,61021400,Cuotas y Suscripciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52021500,61021500,Alojamiento en Hoteles,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5202"
|
||||
do_niif_52030101,61030101,Legales (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030102,61030102,Contabilidad y Auditoría (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030103,61030103,Tecnología (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030104,61030104,Mantenimientos de Planta (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030105,61030105,Mantenimientos de Local (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030106,61030106,Mantenimientos Mobiliarios y Equipos (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030107,61030107,Asesorías (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030108,61030108,Fumigaciones (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030109,61030109,Copias y Escaneos (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030110,61030110,Servicios de Vigilancia (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030111,61030111,Otros Servicios Profesionales (P. Física),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520301"
|
||||
do_niif_52030201,61030201,Legales (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030202,61030202,Contabilidad y Auditoría (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030203,61030203,Tecnología (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030204,61030204,Mantenimiento de Planta (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030205,61030205,Mantenimiento del Local (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030206,61030206,Mantenimiento Mobiliario y Equipos (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030207,61030207,Asesorías (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030208,61030208,Fumigaciones (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030209,61030209,Copias y Escaneos (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030210,61030210,Servicios de Vigilancia (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030211,61030211,Otros Servicios Profesionales (P. Jurídica),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520302"
|
||||
do_niif_52030301,61030301,Honorarios por Servicios del Exterior - Relacionadas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520303"
|
||||
do_niif_52030302,61030302,Honorarios por Servicios del Exterior - Terceros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5203,account_tag_520303"
|
||||
do_niif_52040100,61040100,Gastos por Depreciación de Edificios,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52040200,61040200,Gastos por Depreciación de Equipo de Transporte,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52040300,61040300,Gastos por Depreciación de Mobiliario y Equipos,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52040400,61040400,Gastos por Depreciación de Maquinaria,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52040500,61040500,Gastos por Depreciación de Herramientas,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52040600,61040600,Gastos por Depreciación de Instalaciones,account.data_account_type_depreciation,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5204"
|
||||
do_niif_52050100,61050100,Gastos por Reparación de Edificios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52050200,61050200,Gastos por Reparación de Equipo de Transporte,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52050300,61050300,Gastos por Reparación de Mobiliario y Equipos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52050400,61050400,Gastos por Reparación de Maquinaria,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52050500,61050500,Gastos por Reparación de Herramientas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52050600,61050600,Gastos por Reparación de Instalaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5205"
|
||||
do_niif_52060100,61060100,Relaciones Públicas,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060200,61060200,Publicidad,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060300,61060300,Gastos de Viajes y Representación,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060400,61060400,Donaciones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060500,61060500,Donaciones a ProIndustria (Ley 392-07),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060600,61060600,Promociones,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52060700,61060700,Gastos en Restaurantes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5206"
|
||||
do_niif_52070100,61070100,Gastos por Préstamos Financieros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070200,61070200,Retención por Cheques o Transferencias Electrónicas (0.15%),account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070300,61070300,Intereses Bancarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070400,61070400,Comisiones Bancarias,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070500,61070500,Comisiones de Tarjeta de Crédito,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070600,61070600,Cargos Bancarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070700,61070700,Seguro sobre Préstamos Bancarios,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070800,61070800,Pérdidas por Diferencia Cambiaria,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52070900,61070900,Otro Gastos Financieros,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5207"
|
||||
do_niif_52080100,61080100,Pérdidas por Faltante en Caja,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080200,61080200,Pérdidas por Ventas de Activos Fijos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080300,61080300,Pérdidas por Cuentas Incobrables,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080400,61080400,Gastos por ISR,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080500,61080500,Impuestos a los Activos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080600,61080600,Gastos por Penalidades/Recargos de DGII,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080700,61080700,Gastos por Penalidades/Recargos de TSS,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080800,61080800,Gastos sin Comprobantes,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52080900,61080900,Gastos No Deducibles,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_52081000,61081000,Gastos por Impuestos,account.data_account_type_expenses,FALSE,do_chart_template,"account_tag_6,account_tag_52,account_tag_5208"
|
||||
do_niif_61010100,71010100,Ganancias o Pérdidas,account.data_unaffected_earnings,FALSE,do_chart_template,"account_tag_7,account_tag_61,account_tag_6101"
|
||||
|
||||
|
@@ -2,20 +2,9 @@
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<!-- Chart template for Taxes -->
|
||||
<!-- Taxes Groups -->
|
||||
<record id="group_itbis" model="account.tax.group">
|
||||
<field name="name">ITBIS</field>
|
||||
</record>
|
||||
<record id="group_ret" model="account.tax.group">
|
||||
<field name="name">Retenciones</field>
|
||||
</record>
|
||||
<record id="group_tax" model="account.tax.group">
|
||||
<field name="name">Otros Impuestos</field>
|
||||
</record>
|
||||
<!-- Taxes Template -->
|
||||
<record id="tax_0_sale" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">50</field>
|
||||
<field name="sequence">4</field>
|
||||
<field name="name">Exento ITBIS Ventas</field>
|
||||
<field name="description">Exento</field>
|
||||
<field name="amount">0</field>
|
||||
@@ -27,7 +16,7 @@
|
||||
</record>
|
||||
<record id="tax_0_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">50</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="name">Exento ITBIS Compras</field>
|
||||
<field name="description">Exento</field>
|
||||
<field name="amount">0</field>
|
||||
@@ -49,11 +38,11 @@
|
||||
<field name="refund_account_id" ref="do_niif_21030102"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_V_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_18_sale_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">10</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="name">18% ITBIS Incl. Ventas</field>
|
||||
<field name="description">18% Incl</field>
|
||||
<field name="amount">18</field>
|
||||
@@ -63,35 +52,139 @@
|
||||
<field name="refund_account_id" ref="do_niif_21030102"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_V_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_tip_sale" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">3</field>
|
||||
<field name="name">10% Propina Legal</field>
|
||||
<field name="description">10%</field>
|
||||
<field name="amount">10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_id" ref="do_niif_21030503"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030503"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_tip"/>
|
||||
</record>
|
||||
<record id="tax_18_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">18% ITBIS Compras</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="sequence">11</field>
|
||||
<field name="description">18%</field>
|
||||
<field name="amount">18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_C_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_18_purch_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">20</field>
|
||||
<field name="sequence">12</field>
|
||||
<field name="name">18% ITBIS Incl. Compras</field>
|
||||
<field name="description">18%</field>
|
||||
<field name="amount">18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_C_ITBIS_18_Incluido')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_16_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">16% ITBIS Compras</field>
|
||||
<field name="sequence">13</field>
|
||||
<field name="description">16%</field>
|
||||
<field name="amount">16</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_16_purch_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">16% ITBIS Incl. Compras</field>
|
||||
<field name="sequence">14</field>
|
||||
<field name="description">16%</field>
|
||||
<field name="amount">16</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_9_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">9% ITBIS Compras</field>
|
||||
<field name="sequence">15</field>
|
||||
<field name="description">9% (L690-16)</field>
|
||||
<field name="amount">9</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_9_purch_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">9% ITBIS Incl. Compras</field>
|
||||
<field name="sequence">16</field>
|
||||
<field name="description">9% (L690-16)</field>
|
||||
<field name="amount">9</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_8_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">8% ITBIS Compras</field>
|
||||
<field name="sequence">17</field>
|
||||
<field name="description">8% (L690-16)</field>
|
||||
<field name="amount">8</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_8_purch_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">8% ITBIS Incl. Compras</field>
|
||||
<field name="sequence">18</field>
|
||||
<field name="description">8% (L690-16)</field>
|
||||
<field name="amount">8</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080101"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_tip_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">19</field>
|
||||
<field name="name">10% Propina Legal</field>
|
||||
<field name="description">10%</field>
|
||||
<field name="amount">10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_52080900"/>
|
||||
<field name="refund_account_id" ref="do_niif_52080900"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_tip"/>
|
||||
</record>
|
||||
<record id="tax_18_purch_serv" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -100,12 +193,12 @@
|
||||
<field name="description">18%</field>
|
||||
<field name="amount">18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_11080102"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080102"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_C_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_18_purch_serv_incl" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -114,12 +207,12 @@
|
||||
<field name="description">18%</field>
|
||||
<field name="amount">18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_11080102"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080102"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_C_ITBIS_18_Incluido')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_18_importation" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -128,12 +221,12 @@
|
||||
<field name="description">18%</field>
|
||||
<field name="amount">18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_11080103"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080103"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_IMP_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_18"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_18_of_10" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -142,11 +235,11 @@
|
||||
<field name="description">18% del 10%</field>
|
||||
<field name="amount">1.8</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_11080101"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080302"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_id" ref="do_niif_21030102"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030102"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_itbis"/>
|
||||
</record>
|
||||
<record id="tax_0015_bank" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -159,7 +252,7 @@
|
||||
<field name="account_id" ref="do_niif_52070200"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field eval="1" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_00015"/>
|
||||
<field name="tax_group_id" ref="group_tax"/>
|
||||
</record>
|
||||
<record id="tax_10_telco" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -168,12 +261,12 @@
|
||||
<field name="description">ISC</field>
|
||||
<field name="amount">10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_52020200"/>
|
||||
<field name="refund_account_id" ref="do_niif_52020200"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_TELE_ISC')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="tax_group_isc"/>
|
||||
</record>
|
||||
<record id="tax_2_telco" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -182,12 +275,12 @@
|
||||
<field name="description">CDT</field>
|
||||
<field name="amount">2</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_52020200"/>
|
||||
<field name="refund_account_id" ref="do_niif_52020200"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_TELE_CDT')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_tax"/>
|
||||
</record>
|
||||
<record id="tax_group_telco" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -197,13 +290,26 @@
|
||||
<field name="amount_type">group</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('tax_10_telco'), ref('tax_2_telco')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="tax_group_isc"/>
|
||||
</record>
|
||||
<record id="ret_100_tax_security" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 100% Servicios de Seguridad (N07-09)</field>
|
||||
<field name="description">100% ITBIS</field>
|
||||
<field name="amount">-18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030201"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030201"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_100_tax_nonprofit" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 100% a No Lucrativas (Servicios)</field>
|
||||
<field name="description">100% del ITBIS</field>
|
||||
<field name="sequence">41</field>
|
||||
<field name="name">Retención ITBIS 100% Servicios No Lucrativas (N01-11)</field>
|
||||
<field name="description">100% ITBIS</field>
|
||||
<field name="amount">-18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
@@ -211,13 +317,13 @@
|
||||
<field name="refund_account_id" ref="do_niif_21030203"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_18"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_100_tax_person" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 100% a Persona Física</field>
|
||||
<field name="description">100% del ITBIS</field>
|
||||
<field name="sequence">42</field>
|
||||
<field name="name">Retención ITBIS 100% Servicios a Físicas (R293-11)</field>
|
||||
<field name="description">100% ITBIS</field>
|
||||
<field name="amount">-18</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
@@ -225,169 +331,211 @@
|
||||
<field name="refund_account_id" ref="do_niif_21030202"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ITBIS_18')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_30_tax_moral" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 30% a Persona Jurídica (Construcción)</field>
|
||||
<field name="description">30% del ITBIS</field>
|
||||
<field name="sequence">43</field>
|
||||
<field name="name">Retención ITBIS 30% Servicios a Jurídicas (N02-05)</field>
|
||||
<field name="description">30% ITBIS</field>
|
||||
<field name="amount">-5.4</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030201"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030201"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_30_tax_freelance" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 30% a Profesionales Liberales (Servicios)</field>
|
||||
<field name="description">30% del ITBIS</field>
|
||||
<field name="sequence">43</field>
|
||||
<field name="name">Retención ITBIS 30% Servicios Profesionales (N02-05)</field>
|
||||
<field name="description">30% ITBIS</field>
|
||||
<field name="amount">-5.4</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030204"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030204"/>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_21030201"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030201"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_54"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_75_tax_nonformal" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ITBIS 75% a Proveedores Informales (Bienes)</field>
|
||||
<field name="description">75% del ITBIS</field>
|
||||
<field name="sequence">44</field>
|
||||
<field name="name">Retención ITBIS 75% Bienes a Informales (N08-10)</field>
|
||||
<field name="description">75% ITBIS</field>
|
||||
<field name="amount">-13.5</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030205"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030205"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="ret_10_income_person" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ISR 10% Honorarios a Persona Física (Servicios)</field>
|
||||
<field name="name">Retención ISR 10% Servicios a Físicas</field>
|
||||
<field name="description">10% ISR</field>
|
||||
<field name="amount">-10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_21030301"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030301"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ISR_10')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_10"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_10_income_rent" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ISR 10% a Persona Física (Alquiler)</field>
|
||||
<field name="sequence">50</field>
|
||||
<field name="name">Retención ISR 10% Alquileres a Físicas</field>
|
||||
<field name="description">10% ISR</field>
|
||||
<field name="amount">-10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030302"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030302"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ISR_10')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_10"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_10_income_dividend" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ISR 10% por Dividendos</field>
|
||||
<field name="sequence">51</field>
|
||||
<field name="name">Retención ISR 10% por Dividendos (L253-12)</field>
|
||||
<field name="description">10% ISR</field>
|
||||
<field name="amount">-10</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030303"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030303"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ISR_10')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_10"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_2_income_person" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="sequence">52</field>
|
||||
<field name="name">Retención ISR 2% a Persona Física (Servicios)</field>
|
||||
<field name="description">2% ISR (N 07-07)</field>
|
||||
<field name="description">2% ISR (N07-07)</field>
|
||||
<field name="amount">-2</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_21030308"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030308"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ISR_2')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_2_income_transfer" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="sequence">53</field>
|
||||
<field name="name">Retención ISR 2% por Transferencia de Títulos</field>
|
||||
<field name="description">2% ISR</field>
|
||||
<field name="amount">-2</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030306"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030306"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field eval="[(6,0,[ref('tag_R_ISR_2')])]" name="tag_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_2"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_27_income_remittance" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">40</field>
|
||||
<field name="name">Retención ISR 27% por Remesas al Exterior</field>
|
||||
<field name="sequence">49</field>
|
||||
<field name="name">Retención ISR 27% por Remesas al Exterior (L253-12)</field>
|
||||
<field name="description">27% ISR</field>
|
||||
<field name="amount">-27</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_id" ref="do_niif_21030307"/>
|
||||
<field name="refund_account_id" ref="do_niif_11080303"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030307"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="tax_group_retencion_27"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="ret_5_income_gov" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">50</field>
|
||||
<field name="name">Retención ISR 5% Gubernamentales</field>
|
||||
<field name="description">-5% ISR</field>
|
||||
<field name="amount">-5</field>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="account_id" ref="do_niif_21030308"/>
|
||||
<field name="refund_account_id" ref="do_niif_21030308"/>
|
||||
<field eval="0" name="price_include"/>
|
||||
<field name="tax_group_id" ref="group_isr"/>
|
||||
</record>
|
||||
<record id="tax_group_nonformal" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">60</field>
|
||||
<field name="name">Retención a Proveedores Informales (Bienes)</field>
|
||||
<field name="name">Retención a Proveedores Informales de Bienes</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('ret_75_tax_nonformal'), ref('tax_18_purch')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field eval="[(6, 0, [ref('tax_18_purch'), ref('ret_75_tax_nonformal')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_person_construction" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">60</field>
|
||||
<field name="sequence">61</field>
|
||||
<field name="name">Retención a Persona Física (Servicios Construcción con Materiales)</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('tax_18_of_10'), ref('ret_2_income_person'), ref('ret_100_tax_person')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_moral_construction" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">60</field>
|
||||
<field name="sequence">62</field>
|
||||
<field name="name">Retención a Jurídica (Servicios Construcción con Materiales)</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('ret_30_tax_moral'), ref('tax_18_of_10')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field name="type_tax_use">none</field>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_person_services" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">60</field>
|
||||
<field name="name">Retención a Persona Física por Servicios Profesionales</field>
|
||||
<field name="sequence">58</field>
|
||||
<field name="name">Retención a Físicas por Servicios Profesionales</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('ret_2_income_person'), ref('ret_100_tax_person')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="tax_group_itbis_0"/>
|
||||
<field eval="[(6, 0, [ref('tax_18_purch'), ref('ret_100_tax_person'), ref('ret_2_income_person')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_moral_services" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">58</field>
|
||||
<field name="name">Retención a Jurídicas por Servicios Profesionales</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('tax_18_purch'), ref('ret_30_tax_moral')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_restaurant_sale" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">64</field>
|
||||
<field name="name">Ventas del Restaurante</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field eval="[(6, 0, [ref('tax_18_sale'), ref('tax_tip_sale')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
<record id="tax_group_restaurant_purch" model="account.tax.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="sequence">65</field>
|
||||
<field name="name">Compras a Restaurantes</field>
|
||||
<field name="amount_type">group</field>
|
||||
<field eval="0" name="amount"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field eval="[(6, 0, [ref('tax_18_purch'), ref('tax_tip_purch')])]" name="children_tax_ids"/>
|
||||
<field name="tax_group_id" ref="group_ret"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
@@ -425,7 +425,7 @@
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5' model='account.account.tag'>
|
||||
<field name='name'>5 Costos, Gastos y Pérdidas</field>
|
||||
<field name='name'>5 Costos Directos e Indirectos</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
@@ -448,110 +448,116 @@
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_6' model='account.account.tag'>
|
||||
<field name='name'>6 Gastos y Pérdidas</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_52' model='account.account.tag'>
|
||||
<field name='name'>52 Gastos de Operación</field>
|
||||
<field name='name'>61 Gastos de Operación</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5201' model='account.account.tag'>
|
||||
<field name='name'>5201 Gastos de Personal</field>
|
||||
<field name='name'>6101 Gastos de Personal</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_520101' model='account.account.tag'>
|
||||
<field name='name'>520101 Aportes a la Seguridad Social</field>
|
||||
<field name='name'>610101 Aportes a la Seguridad Social</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_520102' model='account.account.tag'>
|
||||
<field name='name'>520102 Otras Cargas Patronales</field>
|
||||
<field name='name'>610102 Otras Cargas Patronales</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5202' model='account.account.tag'>
|
||||
<field name='name'>5202 Gastos de Administración</field>
|
||||
<field name='name'>6102 Gastos de Administración</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5203' model='account.account.tag'>
|
||||
<field name='name'>5203 Gastos por Trabajo, Suministros y Servicios</field>
|
||||
<field name='name'>6103 Gastos por Trabajo, Suministros y Servicios</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_520301' model='account.account.tag'>
|
||||
<field name='name'>520301 Gastos Honorarios por Servicios Profesionales (P. Física)</field>
|
||||
<field name='name'>610301 Gastos Honorarios por Servicios Profesionales (P. Física)</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_520302' model='account.account.tag'>
|
||||
<field name='name'>520302 Gastos Honorarios por Servicios Profesionales (P. Jurídica)</field>
|
||||
<field name='name'>610302 Gastos Honorarios por Servicios Profesionales (P. Jurídica)</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_520303' model='account.account.tag'>
|
||||
<field name='name'>520303 Gastos Honorarios por Servicios Profesionales (P. Jurídica)</field>
|
||||
<field name='name'>610303 Gastos Honorarios por Servicios Profesionales (P. Jurídica)</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5204' model='account.account.tag'>
|
||||
<field name='name'>5204 Gastos por Depreciación</field>
|
||||
<field name='name'>6104 Gastos por Depreciación</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5205' model='account.account.tag'>
|
||||
<field name='name'>5205 Gastos por Reparaciones</field>
|
||||
<field name='name'>6105 Gastos por Reparaciones</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5206' model='account.account.tag'>
|
||||
<field name='name'>5206 Gastos de Representación</field>
|
||||
<field name='name'>6106 Gastos de Representación</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5207' model='account.account.tag'>
|
||||
<field name='name'>5207 Gastos Financieros</field>
|
||||
<field name='name'>6107 Gastos Financieros</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_5208' model='account.account.tag'>
|
||||
<field name='name'>5208 Gastos Extraordinarios</field>
|
||||
<field name='name'>6108 Gastos Extraordinarios</field>
|
||||
<field name='color'>4</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_6' model='account.account.tag'>
|
||||
<field name='name'>6 Cuentas Liquidadoras de Resultados</field>
|
||||
<record id='account_tag_7' model='account.account.tag'>
|
||||
<field name='name'>7 Cuentas Liquidadoras de Resultados</field>
|
||||
<field name='color'>5</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_61' model='account.account.tag'>
|
||||
<field name='name'>61 Cuenta Liquidadora</field>
|
||||
<field name='name'>71 Cuenta Liquidadora</field>
|
||||
<field name='color'>5</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_6101' model='account.account.tag'>
|
||||
<field name='name'>6101 Pérdidas y Ganancias</field>
|
||||
<field name='name'>7101 Pérdidas y Ganancias</field>
|
||||
<field name='color'>5</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
<record id='account_tag_6102' model='account.account.tag'>
|
||||
<field name='name'>6102 Gastos por Impuestos</field>
|
||||
<field name='name'>7102 Gastos por Impuestos</field>
|
||||
<field name='color'>5</field>
|
||||
<field name='applicability'>accounts</field>
|
||||
</record>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
<odoo>
|
||||
<!-- Chart Template for Defaults -->
|
||||
<record id="do_chart_template" model="account.chart.template">
|
||||
<field eval="True" name="use_anglo_saxon"/>
|
||||
<field name="property_account_receivable_id" ref="do_niif_11030201"/>
|
||||
<field name="property_account_payable_id" ref="do_niif_21010200"/>
|
||||
<field name="property_account_expense_categ_id" ref="do_niif_51010100"/>
|
||||
<field name="property_account_income_categ_id" ref="do_niif_41010100"/>
|
||||
<field eval="False" name="use_anglo_saxon"/>
|
||||
<field name="property_account_expense_categ_id" ref="do_niif_51010100"/>
|
||||
<field name="property_stock_account_input_categ_id" ref="do_niif_21021200"/>
|
||||
<field name="property_stock_account_output_categ_id" ref="do_niif_11050600"/>
|
||||
<field name="property_stock_valuation_account_id" ref="do_niif_11050100"/>
|
||||
|
||||
@@ -3,8 +3,26 @@
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Account Tax Group -->
|
||||
<record id="group_itbis" model="account.tax.group">
|
||||
<field name="name">ITBIS</field>
|
||||
</record>
|
||||
<record id="group_isr" model="account.tax.group">
|
||||
<field name="name">ISR</field>
|
||||
</record>
|
||||
<record id="group_ret" model="account.tax.group">
|
||||
<field name="name">Retenciones</field>
|
||||
</record>
|
||||
<record id="group_tax" model="account.tax.group">
|
||||
<field name="name">Otros Impuestos</field>
|
||||
</record>
|
||||
<record id="tax_group_isc" model="account.tax.group">
|
||||
<field name="name">ISC</field>
|
||||
</record>
|
||||
<record id="tax_group_itbis_0" model="account.tax.group">
|
||||
<field name="name">ITBIS 0%</field>
|
||||
<field name="name">Exento</field>
|
||||
</record>
|
||||
<record id="tax_group_tip" model="account.tax.group">
|
||||
<field name="name">Propina</field>
|
||||
</record>
|
||||
<record id="tax_group_itbis_18" model="account.tax.group">
|
||||
<field name="name">ITBIS 18%</field>
|
||||
@@ -13,19 +31,19 @@
|
||||
<field name="name">ITBIS 0.0015%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_2" model="account.tax.group">
|
||||
<field name="name">Retencion 2%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_54" model="account.tax.group">
|
||||
<field name="name">Retencion 5.4%</field>
|
||||
<field name="name">ISR -2%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_10" model="account.tax.group">
|
||||
<field name="name">Retencion 10%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_18" model="account.tax.group">
|
||||
<field name="name">Retencion 18%</field>
|
||||
<field name="name">ISR -10%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_27" model="account.tax.group">
|
||||
<field name="name">Retencion 27%</field>
|
||||
<field name="name">ISR -27%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_54" model="account.tax.group">
|
||||
<field name="name">ITBIS -30%</field>
|
||||
</record>
|
||||
<record id="tax_group_retencion_18" model="account.tax.group">
|
||||
<field name="name">ITBIS -100%</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -5,41 +5,25 @@
|
||||
<!-- Fiscal Position Templates -->
|
||||
<!-- = = = = = = = = = = = = = = = -->
|
||||
<!-- Principal Fiscal Position for Dominican Republic internally -->
|
||||
<record id="position_buyer_final" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Consumidor Final</field>
|
||||
</record>
|
||||
<record id="position_buyer_moral" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Crédito Fiscal</field>
|
||||
</record>
|
||||
<record id="position_provider_moral" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Proveedor Fiscal</field>
|
||||
</record>
|
||||
<record id="position_construction_moral" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Proveedor Fiscal (Construcción)</field>
|
||||
</record>
|
||||
<record id="position_construction_person" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Persona Física (Construcción)</field>
|
||||
</record>
|
||||
<record id="position_person" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Persona Física</field>
|
||||
<field name="name">P. Física de Servicios</field>
|
||||
</record>
|
||||
<record id="position_service_moral" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">P. Jurídica de Servicios</field>
|
||||
</record>
|
||||
<record id="position_security_moral" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">P. Jurídica de Vigilancia</field>
|
||||
</record>
|
||||
<record id="position_nonformal" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Proveedor Informal (Bienes)</field>
|
||||
<field name="name">Proveedor Informal de Bienes</field>
|
||||
</record>
|
||||
<record id="position_exterior" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Proveedor del Exterior</field>
|
||||
</record>
|
||||
<record id="position_expenses" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Gastos Menores</field>
|
||||
<field name="name">Servicios del Exterior</field>
|
||||
</record>
|
||||
<record id="position_gov" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
@@ -47,12 +31,20 @@
|
||||
</record>
|
||||
<record id="position_nonprofit" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">No lucrativas</field>
|
||||
<field name="name">No Lucrativa de Servicios</field>
|
||||
</record>
|
||||
<record id="position_especial" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Regímenes Especiales</field>
|
||||
</record>
|
||||
<record id="position_restaurant" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Restaurantes</field>
|
||||
</record>
|
||||
<record id="position_restaurant_takeout" model="account.fiscal.position.template">
|
||||
<field name="chart_template_id" ref="do_chart_template"/>
|
||||
<field name="name">Para Llevar</field>
|
||||
</record>
|
||||
<!-- = = = = = = = = = = = = = = = -->
|
||||
<!-- Fiscal Position Tax Templates -->
|
||||
<!-- = = = = = = = = = = = = = = = -->
|
||||
@@ -68,7 +60,7 @@
|
||||
<field name="position_id" ref="position_nonformal"/>
|
||||
<field name="tax_dest_id" ref="tax_group_nonformal"/>
|
||||
</record>
|
||||
<!-- Persona Física>-->
|
||||
<!-- Persona Física de Servicios>-->
|
||||
<record id="fiscal_position_tax_9" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_person"/>
|
||||
@@ -83,38 +75,38 @@
|
||||
<record id="fiscal_position_tax_1" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_sale"/>
|
||||
<field name="position_id" ref="position_gov"/>
|
||||
<field name="tax_dest_id" ref="tax_0_sale"/>
|
||||
<field name="tax_dest_id" ref="ret_5_income_gov"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_2" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="tax_src_id" ref="tax_18_sale_incl"/>
|
||||
<field name="position_id" ref="position_gov"/>
|
||||
<field name="tax_dest_id" ref="tax_0_purch"/>
|
||||
<field name="tax_dest_id" ref="ret_5_income_gov"/>
|
||||
</record>
|
||||
<!-- No Lucrativas -->
|
||||
<record id="fiscal_position_tax_12" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_nonprofit"/>
|
||||
<field name="tax_dest_id" ref="tax_0_purch"/>
|
||||
<field name="tax_dest_id" ref="ret_100_tax_nonprofit"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_13" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch_serv"/>
|
||||
<field name="tax_src_id" ref="tax_18_purch_incl"/>
|
||||
<field name="position_id" ref="position_nonprofit"/>
|
||||
<field name="tax_dest_id" ref="ret_100_tax_nonprofit"/>
|
||||
</record>
|
||||
<!-- Proveedor Moral Construcción -->
|
||||
<!-- Proveedor Moral de Seguridad -->
|
||||
<record id="fiscal_position_tax_8" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_construction_moral"/>
|
||||
<field name="tax_dest_id" ref="tax_group_moral_construction"/>
|
||||
<field name="position_id" ref="position_security_moral"/>
|
||||
<field name="tax_dest_id" ref="ret_100_tax_security"/>
|
||||
</record>
|
||||
<!-- Persona Física Construcción -->
|
||||
<!-- Proveedor Moral de Servicio -->
|
||||
<record id="fiscal_position_tax_7" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_construction_person"/>
|
||||
<field name="tax_dest_id" ref="tax_group_person_construction"/>
|
||||
<field name="position_id" ref="position_service_moral"/>
|
||||
<field name="tax_dest_id" ref="tax_group_moral_services"/>
|
||||
</record>
|
||||
<!-- Importación / Exportación -->
|
||||
<!-- Proveedo del Exterior -->
|
||||
<!-- Proveedor del Exterior -->
|
||||
<record id="fiscal_position_tax_5" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch_serv"/>
|
||||
<field name="position_id" ref="position_exterior"/>
|
||||
@@ -123,8 +115,54 @@
|
||||
<record id="fiscal_position_tax_6" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_exterior"/>
|
||||
<field name="tax_dest_id" ref="tax_0_purch"/>
|
||||
<field name="tax_dest_id" ref="ret_27_income_remittance"/>
|
||||
</record>
|
||||
<!-- Restaurantes -->
|
||||
<record id="fiscal_position_tax_14" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch"/>
|
||||
<field name="position_id" ref="position_restaurant"/>
|
||||
<field name="tax_dest_id" ref="tax_group_restaurant_purch"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_15" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_purch_incl"/>
|
||||
<field name="position_id" ref="position_restaurant"/>
|
||||
<field name="tax_dest_id" ref="tax_group_restaurant_purch"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_16" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_sale"/>
|
||||
<field name="position_id" ref="position_restaurant"/>
|
||||
<field name="tax_dest_id" ref="tax_group_restaurant_sale"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_17" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_sale_incl"/>
|
||||
<field name="position_id" ref="position_restaurant"/>
|
||||
<field name="tax_dest_id" ref="tax_group_restaurant_sale"/>
|
||||
</record>
|
||||
|
||||
<!-- Restaurantes Take-Out -->
|
||||
<record id="fiscal_position_tax_18" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_group_restaurant_sale"/>
|
||||
<field name="position_id" ref="position_restaurant_takeout"/>
|
||||
<field name="tax_dest_id" ref="tax_18_sale"/>
|
||||
</record>
|
||||
|
||||
<!-- Regímenes Especiales -->
|
||||
<record id="fiscal_position_tax_19" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_sale"/>
|
||||
<field name="position_id" ref="position_especial"/>
|
||||
<field name="tax_dest_id" ref="tax_0_sale"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_20" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_18_sale_incl"/>
|
||||
<field name="position_id" ref="position_especial"/>
|
||||
<field name="tax_dest_id" ref="tax_0_sale"/>
|
||||
</record>
|
||||
<record id="fiscal_position_tax_21" model="account.fiscal.position.tax.template">
|
||||
<field name="tax_src_id" ref="tax_group_restaurant_sale"/>
|
||||
<field name="position_id" ref="position_especial"/>
|
||||
<field name="tax_dest_id" ref="tax_tip_sale"/>
|
||||
</record>
|
||||
|
||||
<!-- = = = = = = = = = = = = = = = = = -->
|
||||
<!-- Fiscal Position Accounts Template -->
|
||||
<!-- = = = = = = = = = = = = = = = = = -->
|
||||
|
||||
@@ -11,8 +11,8 @@ class WizardMultiChartsAccounts(models.TransientModel):
|
||||
def _get_default_bank_account_ids(self):
|
||||
if self.env.user.company_id.country_id and self.env.user.company_id.country_id.code.upper() == 'DO':
|
||||
return [
|
||||
{'acc_name': _('Cash'), 'account_type': 'cash'},
|
||||
{'acc_name': _('Caja Chica'), 'account_type': 'cash'},
|
||||
{'acc_name': _('Bank'), 'account_type': 'bank'}
|
||||
]
|
||||
{'acc_name': _('Cash'), 'account_type': 'cash'},
|
||||
{'acc_name': _('Caja Chica'), 'account_type': 'cash'},
|
||||
{'acc_name': _('Bank'), 'account_type': 'bank'}
|
||||
]
|
||||
return super(WizardMultiChartsAccounts, self)._get_default_bank_account_ids()
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
border: none;
|
||||
}
|
||||
.o_composer_button_full_composer {
|
||||
.o-position-absolute(0, 0);
|
||||
.o-position-absolute(auto, 0);
|
||||
}
|
||||
@media (max-width: @screen-xs-max) {
|
||||
.o_composer_button_send {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@mail-thread-avatar-size: 36px;
|
||||
@mail-thread-icon-opacity: 0.6;
|
||||
@mail-thread-side-date-opacity: 0.6;
|
||||
@mail-thread-note: @gray-lighter;
|
||||
@mail-thread-note: fade(@gray-lighter-dark, 50%);
|
||||
|
||||
.o_mail_thread, .o_mail_activity {
|
||||
.o_thread_show_more {
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
&.o_mail_not_discussion {
|
||||
background-color: @mail-thread-note;
|
||||
border-bottom: 1px solid @gray-lighter-dark;
|
||||
border-bottom: 1px solid @gray-lighter-darker;
|
||||
}
|
||||
|
||||
.o_thread_message_sidebar {
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<!-- title -->
|
||||
<field name="name"/>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<div class="o_kanban_inline_block mt16 mr4">
|
||||
<div class="o_kanban_inline_block mr4">
|
||||
<field name="activity_ids" widget="kanban_activity" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -89,6 +89,7 @@ class WebsitePayment(http.Controller):
|
||||
'amount': float(amount),
|
||||
'currency_id': currency_id,
|
||||
'partner_id': partner_id,
|
||||
'type': 'form_save' if acquirer.save_token else 'form',
|
||||
}
|
||||
|
||||
tx = request.env['payment.transaction'].sudo().create(values)
|
||||
@@ -117,7 +118,8 @@ class WebsitePayment(http.Controller):
|
||||
'amount': float(amount),
|
||||
'currency_id': int(currency_id),
|
||||
'partner_id': partner_id,
|
||||
'payment_token_id': pm_id
|
||||
'payment_token_id': pm_id,
|
||||
'type': 'form_save' if token.acquirer_id.save_token else 'form',
|
||||
}
|
||||
|
||||
tx = request.env['payment.transaction'].sudo().create(values)
|
||||
|
||||
@@ -178,7 +178,7 @@ odoo.define('payment.payment_form', function (require) {
|
||||
}).fail(function (message, data) {
|
||||
self.displayError(
|
||||
_t('Server Error'),
|
||||
_t("We are not able to redirect you to the payment form.<") +
|
||||
_t("We are not able to redirect you to the payment form. ") +
|
||||
data.data.message
|
||||
);
|
||||
});
|
||||
@@ -221,7 +221,7 @@ odoo.define('payment.payment_form', function (require) {
|
||||
var form_data = this.getFormData(inputs_form);
|
||||
var ds = $('input[name="data_set"]', acquirer_form)[0];
|
||||
var wrong_input = false;
|
||||
|
||||
|
||||
inputs_form.toArray().forEach(function (element) {
|
||||
//skip the check of non visible inputs
|
||||
if ($(element).attr('type') == 'hidden') {
|
||||
@@ -397,7 +397,7 @@ odoo.define('payment.payment_form', function (require) {
|
||||
var acquirer_id = this.getAcquirerIdFromRadio(checked_radio);
|
||||
|
||||
// if we clicked on an add new payment radio, display its form
|
||||
if (this.isNewPaymentRadio(checked_radio)) {
|
||||
if (this.isNewPaymentRadio(checked_radio)) {
|
||||
this.$('#o_payment_add_token_acq_' + acquirer_id).removeClass('hidden');
|
||||
}
|
||||
else if (this.isFormPaymentRadio(checked_radio)) {
|
||||
@@ -415,8 +415,14 @@ odoo.define('payment.payment_form', function (require) {
|
||||
},
|
||||
displayError: function (title, message) {
|
||||
var $checkedRadio = this.$('input[type="radio"]:checked'),
|
||||
acquirerID = this.getAcquirerIdFromRadio($checkedRadio[0]),
|
||||
acquirerID = this.getAcquirerIdFromRadio($checkedRadio[0]);
|
||||
var $acquirerForm;
|
||||
if (this.isNewPaymentRadio($checkedRadio[0])) {
|
||||
$acquirerForm = this.$('#o_payment_add_token_acq_' + acquirerID);
|
||||
}
|
||||
else if (this.isFormPaymentRadio($checkedRadio[0])) {
|
||||
$acquirerForm = this.$('#o_payment_form_acq_' + acquirerID);
|
||||
}
|
||||
|
||||
if ($checkedRadio.length === 0) {
|
||||
return new Dialog(null, {
|
||||
|
||||
@@ -11,7 +11,7 @@ import time
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.addons.payment_authorize.controllers.main import AuthorizeController
|
||||
from odoo.tools.float_utils import float_compare
|
||||
from odoo.tools.float_utils import float_compare, float_repr
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -64,7 +64,7 @@ class PaymentAcquirerAuthorize(models.Model):
|
||||
temp_authorize_tx_values = {
|
||||
'x_login': self.authorize_login,
|
||||
'x_trans_key': self.authorize_transaction_key,
|
||||
'x_amount': str(values['amount']),
|
||||
'x_amount': float_repr(values['amount'], values['currency'].decimal_places if values['currency'] else 2),
|
||||
'x_show_form': 'PAYMENT_FORM',
|
||||
'x_type': 'AUTH_CAPTURE' if not self.capture_manually else 'AUTH_ONLY',
|
||||
'x_method': 'CC',
|
||||
|
||||
@@ -48,7 +48,7 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
form_values = {
|
||||
'x_login': self.authorize.authorize_login,
|
||||
'x_trans_key': self.authorize.authorize_transaction_key,
|
||||
'x_amount': '320.0',
|
||||
'x_amount': '56.16',
|
||||
'x_show_form': 'PAYMENT_FORM',
|
||||
'x_type': 'AUTH_CAPTURE',
|
||||
'x_method': 'CC',
|
||||
@@ -84,7 +84,7 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
|
||||
form_values['x_fp_hash'] = self._authorize_generate_hashing(form_values)
|
||||
# render the button
|
||||
res = self.authorize.render('SO004', 320.0, self.currency_usd.id, values=self.buyer_values)
|
||||
res = self.authorize.render('SO004', 56.16, self.currency_usd.id, values=self.buyer_values)
|
||||
# check form result
|
||||
tree = objectify.fromstring(res)
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ class PaymentTransactionStripe(models.Model):
|
||||
@api.multi
|
||||
def stripe_s2s_do_transaction(self, **kwargs):
|
||||
self.ensure_one()
|
||||
result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref)
|
||||
result = self._create_stripe_charge(acquirer_ref=self.payment_token_id.acquirer_ref, email=self.partner_email)
|
||||
return self._stripe_s2s_validate_tree(result)
|
||||
|
||||
|
||||
|
||||
@@ -46,9 +46,11 @@ class PosOrder(models.Model):
|
||||
}
|
||||
|
||||
def _payment_fields(self, ui_paymentline):
|
||||
payment_date = ui_paymentline['name']
|
||||
payment_date = fields.Date.context_today(self, fields.Datetime.from_string(payment_date))
|
||||
return {
|
||||
'amount': ui_paymentline['amount'] or 0.0,
|
||||
'payment_date': ui_paymentline['name'],
|
||||
'payment_date': payment_date,
|
||||
'statement_id': ui_paymentline['statement_id'],
|
||||
'payment_name': ui_paymentline.get('note', False),
|
||||
'journal': ui_paymentline['journal_id'],
|
||||
@@ -413,14 +415,14 @@ class PosOrder(models.Model):
|
||||
return True
|
||||
|
||||
def _get_pos_anglo_saxon_price_unit(self, product, partner_id, quantity):
|
||||
# In the SO part, the entries will be inverted by function compute_invoice_totals
|
||||
price_unit = - product._get_anglo_saxon_price_unit()
|
||||
price_unit = product._get_anglo_saxon_price_unit()
|
||||
if product._get_invoice_policy() == "delivery":
|
||||
moves = self.filtered(lambda o: o.partner_id.id == partner_id).mapped('picking_id.move_lines').filtered(lambda m: m.product_id.id == product.id)
|
||||
moves.sorted(lambda x: x.date)
|
||||
average_price_unit = product._compute_average_price(quantity, quantity, moves)
|
||||
average_price_unit = product._compute_average_price(0, quantity, moves)
|
||||
price_unit = average_price_unit or price_unit
|
||||
return price_unit
|
||||
# In the SO part, the entries will be inverted by function compute_invoice_totals
|
||||
return - price_unit
|
||||
|
||||
def _reconcile_payments(self):
|
||||
for order in self:
|
||||
@@ -811,7 +813,7 @@ class PosOrder(models.Model):
|
||||
"""Create a new payment for the order"""
|
||||
args = {
|
||||
'amount': data['amount'],
|
||||
'date': data.get('payment_date', fields.Date.today()),
|
||||
'date': data.get('payment_date', fields.Date.context_today(self)),
|
||||
'name': self.name + ': ' + (data.get('payment_name', '') or ''),
|
||||
'partner_id': self.env["res.partner"]._find_accounting_partner(self.partner_id).id or False,
|
||||
}
|
||||
|
||||
@@ -941,6 +941,7 @@ exports.PosModel = Backbone.Model.extend({
|
||||
model: 'pos.order',
|
||||
method: 'create_from_ui',
|
||||
args: args,
|
||||
kwargs: {context: session.user_context},
|
||||
}, {
|
||||
timeout: timeout,
|
||||
shadow: !options.to_invoice
|
||||
@@ -1385,7 +1386,8 @@ exports.Orderline = Backbone.Model.extend({
|
||||
if (unit.rounding) {
|
||||
this.quantity = round_pr(quant, unit.rounding);
|
||||
var decimals = this.pos.dp['Product Unit of Measure'];
|
||||
this.quantityStr = field_utils.format.float(round_di(this.quantity, decimals), {digits: [69, decimals]});
|
||||
this.quantity = round_di(this.quantity, decimals)
|
||||
this.quantityStr = field_utils.format.float(this.quantity, {digits: [69, decimals]});
|
||||
} else {
|
||||
this.quantity = round_pr(quant, 1);
|
||||
this.quantityStr = this.quantity.toFixed(0);
|
||||
|
||||
@@ -6,8 +6,10 @@ import math
|
||||
from werkzeug import urls
|
||||
|
||||
from odoo import fields as odoo_fields, tools, _
|
||||
from odoo.osv import expression
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.http import Controller, request, route
|
||||
from odoo.addons.web.controllers.main import WebClient
|
||||
|
||||
# --------------------------------------------------
|
||||
# Misc tools
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import ir_http
|
||||
from . import mail_thread
|
||||
from . import mail_message
|
||||
from . import portal_mixin
|
||||
@@ -0,0 +1,15 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
@classmethod
|
||||
def _get_translation_frontend_modules_domain(cls):
|
||||
domain = super(IrHttp, cls)._get_translation_frontend_modules_domain()
|
||||
return expression.OR([domain, [('name', '=', 'portal')]])
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
is_website_user: <t t-esc="json.dumps(request.env.user._is_public())"/>,
|
||||
user_id: <t t-esc="json.dumps(request.env.user.id)" />,
|
||||
is_frontend: true,
|
||||
translationURL: '/website/translations',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
<!-- This is a test account for testing with test cards and cannot be used in a live environment -->
|
||||
<record id="pos_mercury_configuration" model="pos_mercury.configuration">
|
||||
<field name="name">Mercury Demo</field>
|
||||
<field name="merchant_id">334160</field>
|
||||
<field name="merchant_pwd">81303DUR</field>
|
||||
<field name="merchant_id">755847002</field>
|
||||
<field name="merchant_pwd">xyz</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import logging
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools.float_utils import float_compare
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -71,8 +72,9 @@ class PosOrder(models.Model):
|
||||
statement_id = super(PosOrder, self).add_payment(data)
|
||||
statement_lines = self.env['account.bank.statement.line'].search([('statement_id', '=', statement_id),
|
||||
('pos_statement_id', '=', self.id),
|
||||
('journal_id', '=', data['journal']),
|
||||
('amount', '=', data['amount'])])
|
||||
('journal_id', '=', data['journal'])])
|
||||
statement_lines = statement_lines.filtered(lambda line: float_compare(line.amount, data['amount'],
|
||||
precision_rounding=line.journal_currency_id.rounding) == 0)
|
||||
|
||||
# we can get multiple statement_lines when there are >1 credit
|
||||
# card payments with the same amount. In that case it doesn't
|
||||
|
||||
@@ -61,11 +61,15 @@ class MercuryTransaction(models.Model):
|
||||
'SOAPAction': 'http://www.mercurypay.com/CreditTransaction',
|
||||
}
|
||||
|
||||
url = 'https://w1.mercurypay.com/ws/ws.asmx'
|
||||
if self.env['ir.config_parameter'].sudo().get_param('pos_mercury.enable_test_env'):
|
||||
url = 'https://w1.mercurycert.net/ws/ws.asmx'
|
||||
|
||||
try:
|
||||
r = requests.post('https://w1.mercurypay.com/ws/ws.asmx', data=xml_transaction, headers=headers, timeout=65)
|
||||
r = requests.post(url, data=xml_transaction, headers=headers, timeout=65)
|
||||
r.raise_for_status()
|
||||
response = werkzeug.utils.unescape(r.content.decode())
|
||||
except:
|
||||
except Exception:
|
||||
response = "timeout"
|
||||
|
||||
return response
|
||||
|
||||
@@ -527,7 +527,7 @@ class Task(models.Model):
|
||||
legend_done = fields.Char(related='stage_id.legend_done', string='Kanban Valid Explanation', readonly=True, related_sudo=False)
|
||||
legend_normal = fields.Char(related='stage_id.legend_normal', string='Kanban Ongoing Explanation', readonly=True, related_sudo=False)
|
||||
parent_id = fields.Many2one('project.task', string='Parent Task', index=True)
|
||||
child_ids = fields.One2many('project.task', 'parent_id', string="Sub-tasks")
|
||||
child_ids = fields.One2many('project.task', 'parent_id', string="Sub-tasks", context={'active_test': False})
|
||||
subtask_count = fields.Integer("Sub-task count", compute='_compute_subtask_count')
|
||||
email_from = fields.Char(string='Email', help="These people will receive email.", index=True)
|
||||
email_cc = fields.Char(string='Watchers Emails', help="""These email addresses will be added to the CC field of all inbound
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<field name="route_ids" eval="[(4,ref('route_warehouse0_buy'))]"></field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
|
||||
<record id="purchase_order_1" model="purchase.order">
|
||||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="state">draft</field>
|
||||
@@ -187,5 +187,11 @@
|
||||
<record id="stock.stock_warehouse_shop0" model="stock.warehouse">
|
||||
<field name="buy_to_resupply" eval="True"/>
|
||||
</record>
|
||||
|
||||
<function model="stock.warehouse" name="write">
|
||||
<value model="stock.warehouse" search="[('partner_id', '=', ref('stock.res_partner_company_1'))]"/>
|
||||
<value eval="{'buy_to_resupply': True}"/>
|
||||
</function>
|
||||
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -1050,11 +1050,11 @@ class ProcurementRule(models.Model):
|
||||
def _prepare_purchase_order(self, product_id, product_qty, product_uom, origin, values, partner):
|
||||
schedule_date = self._get_purchase_schedule_date(values)
|
||||
purchase_date = self._get_purchase_order_date(product_id, product_qty, product_uom, values, partner, schedule_date)
|
||||
fpos = self.env['account.fiscal.position'].with_context(company_id=values['company_id'].id).get_fiscal_position(partner.id)
|
||||
fpos = self.env['account.fiscal.position'].with_context(force_company=values['company_id'].id).get_fiscal_position(partner.id)
|
||||
|
||||
gpo = self.group_propagation_option
|
||||
group = (gpo == 'fixed' and self.group_id.id) or \
|
||||
(gpo == 'propagate' and values['group_id'].id) or False
|
||||
(gpo == 'propagate' and 'group_id' in values and values['group_id'].id) or False
|
||||
|
||||
return {
|
||||
'partner_id': partner.id,
|
||||
@@ -1079,7 +1079,7 @@ class ProcurementRule(models.Model):
|
||||
domain = super(ProcurementRule, self)._make_po_get_domain(values, partner)
|
||||
gpo = self.group_propagation_option
|
||||
group = (gpo == 'fixed' and self.group_id) or \
|
||||
(gpo == 'propagate' and values['group_id']) or False
|
||||
(gpo == 'propagate' and 'group_id' in values and values['group_id']) or False
|
||||
|
||||
domain += (
|
||||
('partner_id', '=', partner.id),
|
||||
|
||||
@@ -149,7 +149,7 @@
|
||||
</group>
|
||||
</form>
|
||||
<tree string="Fees" editable="bottom">
|
||||
<field name="product_id" domain="[('type','=','service')]"/>
|
||||
<field name="product_id" domain="[('type','=','service')]" required="True"/>
|
||||
<field name='name'/>
|
||||
<field name="product_uom_qty" string="Quantity"/>
|
||||
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
|
||||
|
||||
@@ -11,6 +11,8 @@ This module contains all the common features of Sales Management and eCommerce.
|
||||
""",
|
||||
'depends': ['sales_team', 'account', 'portal'],
|
||||
'data': [
|
||||
'security/sale_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'data/ir_sequence_data.xml',
|
||||
'data/sale_data.xml',
|
||||
'report/sale_report.xml',
|
||||
@@ -19,8 +21,6 @@ This module contains all the common features of Sales Management and eCommerce.
|
||||
'report/sale_report_templates.xml',
|
||||
'report/invoice_report_templates.xml',
|
||||
'report/report_all_channels_sales_views.xml',
|
||||
'security/sale_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/sale_make_invoice_advance_views.xml',
|
||||
'views/sale_views.xml',
|
||||
'views/account_invoice_views.xml',
|
||||
|
||||
@@ -39,6 +39,9 @@ class AccountInvoice(models.Model):
|
||||
def _onchange_delivery_address(self):
|
||||
addr = self.partner_id.address_get(['delivery'])
|
||||
self.partner_shipping_id = addr and addr.get('delivery')
|
||||
if self.env.context.get('type', 'out_invoice') == 'out_invoice':
|
||||
company = self.company_id or self.env.user.company_id
|
||||
self.comment = company.with_context(lang=self.partner_id.lang).sale_note
|
||||
|
||||
@api.multi
|
||||
def action_invoice_paid(self):
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
string="PRO-FORMA Invoice"
|
||||
model="sale.order"
|
||||
report_type="qweb-pdf"
|
||||
groups="sale.group_proforma_sales"
|
||||
file="sale.report_saleorder_pro_forma"
|
||||
name="sale.report_saleorder_pro_forma"
|
||||
print_report_name="'PRO-FORMA - %s' % (object.name)"
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
<strong>Payment Terms:</strong>
|
||||
<p t-field="doc.payment_term_id"/>
|
||||
</div>
|
||||
<div t-if="doc.validity_date and doc.state in ['draft', 'sent']" class="col-xs-3">
|
||||
<strong>Expiration Date:</strong>
|
||||
<p t-field="doc.validity_date"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Is there a discount on at least one line? -->
|
||||
|
||||
@@ -67,7 +67,7 @@ class SaleAdvancePaymentInv(models.TransientModel):
|
||||
|
||||
account_id = False
|
||||
if self.product_id.id:
|
||||
account_id = self.product_id.property_account_income_id.id
|
||||
account_id = self.product_id.property_account_income_id.id or self.product_id.categ_id.property_account_income_categ_id.id
|
||||
if not account_id:
|
||||
inc_acc = ir_property_obj.get('property_account_income_categ_id', 'product.category')
|
||||
account_id = order.fiscal_position_id.map_account(inc_acc).id if inc_acc else False
|
||||
|
||||
@@ -52,7 +52,6 @@ class StockMoveLine(models.Model):
|
||||
reference = fields.Char(related='move_id.reference', store=True, related_sudo=False)
|
||||
in_entire_package = fields.Boolean(compute='_compute_in_entire_package')
|
||||
|
||||
@api.one
|
||||
def _compute_location_description(self):
|
||||
for operation, operation_sudo in izip(self, self.sudo()):
|
||||
operation.from_loc = '%s%s' % (operation_sudo.location_id.name, operation.product_id and operation_sudo.package_id.name or '')
|
||||
@@ -141,7 +140,7 @@ class StockMoveLine(models.Model):
|
||||
help him. This onchange will warn him if he set `qty_done` to a non-supported value.
|
||||
"""
|
||||
res = {}
|
||||
if self.product_id.tracking == 'serial':
|
||||
if self.qty_done and self.product_id.tracking == 'serial':
|
||||
if float_compare(self.qty_done, 1.0, precision_rounding=self.move_id.product_id.uom_id.rounding) != 0:
|
||||
message = _('You can only process 1.0 %s of products with unique serial number.') % self.product_id.uom_id.name
|
||||
res['warning'] = {'title': _('Warning'), 'message': message}
|
||||
|
||||
@@ -37,6 +37,18 @@ class ProductionLot(models.Model):
|
||||
raise UserError(_("You are not allowed to create a lot for this picking type"))
|
||||
return super(ProductionLot, self).create(vals)
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
if 'product_id' in vals:
|
||||
move_lines = self.env['stock.move.line'].search([('lot_id', 'in', self.ids)])
|
||||
if move_lines:
|
||||
raise UserError(_(
|
||||
'You are not allowed to change the product linked to a serial or lot number ' +
|
||||
'if some stock moves have already been created with that number. ' +
|
||||
'This would lead to inconsistencies in your stock.'
|
||||
))
|
||||
return super(ProductionLot, self).write(vals)
|
||||
|
||||
@api.one
|
||||
def _product_qty(self):
|
||||
# We only care for the quants in internal or transit locations.
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
</template>
|
||||
|
||||
<template id="report_location_barcode">
|
||||
<t t-call="web.basic_layout">
|
||||
<div t-foreach="[docs[x:x+4] for x in xrange(0, len(docs), 4)]" t-as="page_docs" class="page page_stock_location_barcodes">
|
||||
<t t-call="web.html_container">
|
||||
<div t-foreach="[docs[x:x+4] for x in xrange(0, len(docs), 4)]" t-as="page_docs" class="page article page_stock_location_barcodes">
|
||||
<t t-foreach="page_docs" t-as="o">
|
||||
<t t-if="o.barcode"><t t-set="content" t-value="o.barcode"/></t>
|
||||
<t t-if="not o.barcode"><t t-set="content" t-value="o.name"/></t>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="in_entire_package" invisible="1"/>
|
||||
<field name="picking_id" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
@@ -44,7 +46,8 @@
|
||||
<field name="qty_done"/>
|
||||
<field name="product_uom_id" options="{'no_create': True}" string="Unit of Measure" groups="product.group_uom"/>
|
||||
</div>
|
||||
<field name="lot_id" string="Lot/Serial Number" groups="stock.group_production_lot"/>
|
||||
<field name="lot_id" attrs="{'readonly': [('in_entire_package', '=', True)]}" domain="[('product_id', '=', product_id)]" groups="stock.group_production_lot" context="{'default_product_id': product_id, 'active_picking_id': picking_id}"/>
|
||||
<field name="lot_name" attrs="{'readonly': [('in_entire_package', '=', True)]}" groups="stock.group_production_lot"/>
|
||||
<field name="package_id" string="Source Package" groups="product.group_stock_packaging"/>
|
||||
<field name="result_package_id" string="Destination Package" groups="stock.group_tracking_lot"/>
|
||||
<field name="owner_id" string="Owner" groups="stock.group_tracking_owner"/>
|
||||
@@ -86,6 +89,7 @@
|
||||
<field name="model">stock.move.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="in_entire_package"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
@@ -93,6 +97,8 @@
|
||||
<field name="picking_id"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<field name="lot_id" invisible="not context.get('show_lots_m2o')" domain="[('product_id', '=', product_id)]" groups="stock.group_production_lot" context="{'default_product_id': product_id, 'active_picking_id': picking_id}"/>
|
||||
<field name="lot_name" invisible="not context.get('show_lots_text')" groups="stock.group_production_lot"/>
|
||||
<field name="qty_done" string="Quantity Done"/>
|
||||
<field name="product_uom_id" string="Unit of Measure" groups="product.group_uom"/>
|
||||
</div>
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
<field name="product_id"/>
|
||||
<field name="priority"/>
|
||||
<field name="state"/>
|
||||
<field name="show_details_visible"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_global_click">
|
||||
@@ -88,7 +89,11 @@
|
||||
<field name="product_id"/>
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left"/>
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<button name="action_show_details" string="Register lots, packs, location"
|
||||
class="o_icon_button fa fa-list" type="object"
|
||||
attrs="{'invisible': [('show_details_visible', '=', False)]}" options='{"warn": true}'/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<span><field name="product_uom_qty"/></span>
|
||||
</div>
|
||||
|
||||
@@ -26,17 +26,6 @@
|
||||
<field name="value">manual_periodic</field>
|
||||
<field name="type">selection</field>
|
||||
</record>
|
||||
<record id="action_stock_account_valuation_report" model="ir.actions.server">
|
||||
<field name="name">Stock Valuation Report</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="state">code</field>
|
||||
<field name="model_id" ref="product.model_product_product"></field>
|
||||
<field name="binding_model_id" ref="product.model_product_product"></field>
|
||||
<field name="code">
|
||||
env['stock.move']._run_fifo_vacuum()
|
||||
action = env.ref('stock_account.product_valuation_action').read()[0]
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ class ProductTemplate(models.Model):
|
||||
if self.property_cost_method == 'fifo' and self.cost_method in ['average', 'standard']:
|
||||
# Cannot use the `stock_value` computed field as it's already invalidated when
|
||||
# entering this method.
|
||||
valuation = sum([variant._sum_remaining_values() for variant in self.product_variant_ids])
|
||||
valuation = sum([variant._sum_remaining_values()[0] for variant in self.product_variant_ids])
|
||||
qty_available = self.with_context(company_owned=True).qty_available
|
||||
if qty_available:
|
||||
self.standard_price = valuation / qty_available
|
||||
@@ -85,16 +85,8 @@ class ProductTemplate(models.Model):
|
||||
|
||||
@api.multi
|
||||
def action_open_product_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('stock_account.stock_move_valuation_action').read()[0]
|
||||
action['domain'] = [('product_tmpl_id', '=', self.id)]
|
||||
action['context'] = {
|
||||
'search_default_outgoing': True,
|
||||
'search_default_incoming': True,
|
||||
'search_default_done': True,
|
||||
'is_avg': self.cost_method == 'average',
|
||||
}
|
||||
return action
|
||||
# TODO: remove me in master
|
||||
pass
|
||||
|
||||
@api.multi
|
||||
def get_product_accounts(self, fiscal_pos=None):
|
||||
@@ -111,6 +103,12 @@ class ProductProduct(models.Model):
|
||||
|
||||
stock_value = fields.Float(
|
||||
'Value', compute='_compute_stock_value')
|
||||
qty_at_date = fields.Float(
|
||||
'Quantity', compute='_compute_stock_value')
|
||||
stock_fifo_real_time_aml_ids = fields.Many2many(
|
||||
'account.move.line', compute='_compute_stock_value')
|
||||
stock_fifo_manual_move_ids = fields.Many2many(
|
||||
'stock.move', compute='_compute_stock_value')
|
||||
|
||||
@api.multi
|
||||
def do_change_standard_price(self, new_price, account_id):
|
||||
@@ -173,29 +171,99 @@ class ProductProduct(models.Model):
|
||||
StockMove = self.env['stock.move']
|
||||
domain = [('product_id', '=', self.id)] + StockMove._get_all_base_domain()
|
||||
moves = StockMove.search(domain)
|
||||
return sum(moves.mapped('remaining_value'))
|
||||
return sum(moves.mapped('remaining_value')), moves
|
||||
|
||||
@api.multi
|
||||
@api.depends('stock_move_ids.product_qty', 'stock_move_ids.state', 'product_tmpl_id.cost_method')
|
||||
@api.depends('stock_move_ids.product_qty', 'stock_move_ids.state', 'stock_move_ids.remaining_value', 'product_tmpl_id.cost_method', 'product_tmpl_id.standard_price', 'product_tmpl_id.property_valuation', 'product_tmpl_id.categ_id.property_valuation')
|
||||
def _compute_stock_value(self):
|
||||
StockMove = self.env['stock.move']
|
||||
to_date = self.env.context.get('to_date')
|
||||
|
||||
self.env['account.move.line'].check_access_rights('read')
|
||||
fifo_automated_values = {}
|
||||
query = """SELECT aml.product_id, aml.account_id, sum(aml.debit) - sum(aml.credit), sum(quantity), array_agg(aml.id)
|
||||
FROM account_move_line AS aml
|
||||
WHERE aml.product_id IS NOT NULL AND aml.company_id=%%s %s
|
||||
GROUP BY aml.product_id, aml.account_id"""
|
||||
params = (self.env.user.company_id.id,)
|
||||
if to_date:
|
||||
query = query % ('AND aml.date <= %s',)
|
||||
params = params + (to_date,)
|
||||
else:
|
||||
query = query % ('',)
|
||||
self.env.cr.execute(query, params=params)
|
||||
|
||||
res = self.env.cr.fetchall()
|
||||
for row in res:
|
||||
fifo_automated_values[(row[0], row[1])] = (row[2], row[3], list(row[4]))
|
||||
|
||||
for product in self:
|
||||
if product.cost_method in ['standard', 'average']:
|
||||
product.stock_value = product.standard_price * product.with_context(company_owned=True).qty_available
|
||||
qty_available = product.with_context(company_owned=True).qty_available
|
||||
price_used = product.standard_price
|
||||
if to_date:
|
||||
price_used = product.get_history_price(
|
||||
self.env.user.company_id.id,
|
||||
date=to_date,
|
||||
)
|
||||
product.stock_value = price_used * qty_available
|
||||
product.qty_at_date = qty_available
|
||||
elif product.cost_method == 'fifo':
|
||||
product.stock_value = product._sum_remaining_values()
|
||||
if to_date:
|
||||
if product.product_tmpl_id.valuation == 'manual_periodic':
|
||||
domain = [('product_id', '=', product.id), ('date', '<=', to_date)] + StockMove._get_all_base_domain()
|
||||
moves = StockMove.search(domain)
|
||||
product.stock_value = sum(moves.mapped('value'))
|
||||
product.qty_at_date = product.with_context(company_owned=True).qty_available
|
||||
product.stock_fifo_manual_move_ids = StockMove.browse(moves.ids)
|
||||
elif product.product_tmpl_id.valuation == 'real_time':
|
||||
valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
|
||||
value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
|
||||
product.stock_value = value
|
||||
product.qty_at_date = quantity
|
||||
product.stock_fifo_real_time_aml_ids = self.env['account.move.line'].browse(aml_ids)
|
||||
else:
|
||||
product.stock_value, moves = product._sum_remaining_values()
|
||||
product.qty_at_date = product.with_context(company_owned=True).qty_available
|
||||
if product.product_tmpl_id.valuation == 'manual_periodic':
|
||||
product.stock_fifo_manual_move_ids = moves
|
||||
elif product.product_tmpl_id.valuation == 'real_time':
|
||||
valuation_account_id = product.categ_id.property_stock_valuation_account_id.id
|
||||
value, quantity, aml_ids = fifo_automated_values.get((product.id, valuation_account_id)) or (0, 0, [])
|
||||
product.stock_fifo_real_time_aml_ids = self.env['account.move.line'].browse(aml_ids)
|
||||
|
||||
def action_valuation_at_date_details(self):
|
||||
""" Returns an action with either a list view of all the valued stock moves of `self` if the
|
||||
valuation is set as manual or a list view of all the account move lines if the valuation is
|
||||
set as automated.
|
||||
"""
|
||||
self.ensure_one()
|
||||
to_date = self.env.context.get('to_date')
|
||||
action = {
|
||||
'name': _('Valuation at date'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'context': self.env.context,
|
||||
}
|
||||
if self.valuation == 'real_time':
|
||||
action['res_model'] = 'account.move.line'
|
||||
action['domain'] = [('id', 'in', self.with_context(to_date=to_date).stock_fifo_real_time_aml_ids.ids)]
|
||||
tree_view_ref = self.env.ref('stock_account.view_stock_account_aml')
|
||||
form_view_ref = self.env.ref('account.view_move_line_form')
|
||||
action['views'] = [(tree_view_ref.id, 'tree'), (form_view_ref.id, 'form')]
|
||||
else:
|
||||
action['res_model'] = 'stock.move'
|
||||
action['domain'] = [('id', 'in', self.with_context(to_date=to_date).stock_fifo_manual_move_ids.ids)]
|
||||
tree_view_ref = self.env.ref('stock_account.view_move_tree_valuation_at_date')
|
||||
form_view_ref = self.env.ref('stock.view_move_form')
|
||||
action['views'] = [(tree_view_ref.id, 'tree'), (form_view_ref.id, 'form')]
|
||||
return action
|
||||
|
||||
@api.multi
|
||||
def action_open_product_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('stock_account.stock_move_valuation_action').read()[0]
|
||||
action['domain'] = [('product_id', '=', self.id)]
|
||||
action['context'] = {
|
||||
'search_default_outgoing': True,
|
||||
'search_default_incoming': True,
|
||||
'search_default_done': True,
|
||||
'is_avg': self.cost_method == 'average',
|
||||
}
|
||||
return action
|
||||
#TODO: remove me in master
|
||||
pass
|
||||
|
||||
@api.model
|
||||
def _anglo_saxon_sale_move_lines(self, name, product, uom, qty, price_unit, currency=False, amount_currency=False, fiscal_position=False, account_analytic=False, analytic_tags=False):
|
||||
|
||||
@@ -71,37 +71,45 @@ class StockMoveLine(models.Model):
|
||||
if move.product_id.valuation == 'real_time' and (move._is_in() or move._is_out()):
|
||||
move.with_context(force_valuation_amount=correction_value)._account_entry_move()
|
||||
return res
|
||||
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
""" When editing a done stock.move.line, we impact the valuation. Users may increase or
|
||||
decrease the `qty_done` field. There are three cost method available: standard, average
|
||||
and fifo. We implement the logic in a similar way for standard and average: increase
|
||||
or decrease the original value with the standard or average price of today. In fifo, we
|
||||
have a different logic wheter the move is incoming or outgoing. If the move is incoming, we
|
||||
update the value and remaining_value/qty with the unit price of the move. If the move is
|
||||
outgoing and the user increases qty_done, we call _run_fifo and it'll consume layer(s) in
|
||||
the stack the same way a new outgoing move would have done. If the move is outoing and the
|
||||
user decreases qty_done, we either increase the last receipt candidate if one is found or
|
||||
we decrease the value with the last fifo price.
|
||||
"""
|
||||
if 'qty_done' in vals:
|
||||
# We need to update the `value`, `remaining_value` and `remaining_qty` on the linked
|
||||
# stock move.
|
||||
moves_to_update = {}
|
||||
for move_line in self.filtered(lambda ml: ml.state == 'done' and (ml.move_id._is_in() or ml.move_id._is_out())):
|
||||
moves_to_update[move_line.move_id] = vals['qty_done'] - move_line.qty_done
|
||||
|
||||
for move_id, qty_difference in moves_to_update.items():
|
||||
# more/less units are available, update `remaining_value` and
|
||||
# `remaining_qty` on the linked stock move.
|
||||
move_vals = {'remaining_qty': move_id.remaining_qty + qty_difference}
|
||||
new_remaining_value = 0
|
||||
move_vals = {}
|
||||
if move_id.product_id.cost_method in ['standard', 'average']:
|
||||
correction_value = qty_difference * move_id.product_id.standard_price
|
||||
move_vals['value'] = move_id.value - correction_value
|
||||
move_vals.pop('remaining_qty')
|
||||
if move_id._is_in():
|
||||
move_vals['value'] = move_id.value + correction_value
|
||||
elif move_id._is_out():
|
||||
move_vals['value'] = move_id.value - correction_value
|
||||
else:
|
||||
# FIFO handling
|
||||
if move_id._is_in():
|
||||
correction_value = qty_difference * move_id.price_unit
|
||||
new_remaining_value = move_id.remaining_value + correction_value
|
||||
move_vals['value'] = move_id.value + correction_value
|
||||
move_vals['remaining_qty'] = move_id.remaining_qty + qty_difference
|
||||
move_vals['remaining_value'] = move_id.remaining_value + correction_value
|
||||
elif move_id._is_out() and qty_difference > 0:
|
||||
# send more, run fifo again
|
||||
correction_value = self.env['stock.move']._run_fifo(move_id, quantity=qty_difference)
|
||||
new_remaining_value = move_id.remaining_value + correction_value
|
||||
move_vals.pop('remaining_qty')
|
||||
# no need to adapt `remaining_qty` and `remaining_value` as `_run_fifo` took care of it
|
||||
move_vals['value'] = move_id.value - correction_value
|
||||
elif move_id._is_out() and qty_difference < 0:
|
||||
# fake return, find the last receipt and augment its qties
|
||||
candidates_receipt = self.env['stock.move'].search(move_id._get_in_domain(), order='date, id desc', limit=1)
|
||||
if candidates_receipt:
|
||||
candidates_receipt.write({
|
||||
@@ -111,15 +119,11 @@ class StockMoveLine(models.Model):
|
||||
correction_value = qty_difference * candidates_receipt.price_unit
|
||||
else:
|
||||
correction_value = qty_difference * move_id.product_id.standard_price
|
||||
move_vals.pop('remaining_qty')
|
||||
if move_id._is_out():
|
||||
move_vals['remaining_value'] = new_remaining_value if new_remaining_value < 0 else 0
|
||||
else:
|
||||
move_vals['remaining_value'] = new_remaining_value
|
||||
move_vals['value'] = move_id.value - correction_value
|
||||
move_id.write(move_vals)
|
||||
|
||||
if move_id.product_id.valuation == 'real_time':
|
||||
move_id.with_context(force_valuation_amount=correction_value)._account_entry_move()
|
||||
move_id.with_context(force_valuation_amount=correction_value, forced_quantity=qty_difference)._account_entry_move()
|
||||
if qty_difference > 0:
|
||||
move_id.product_price_update_before_done(forced_qty=qty_difference)
|
||||
return super(StockMoveLine, self).write(vals)
|
||||
@@ -210,13 +214,23 @@ class StockMove(models.Model):
|
||||
|
||||
@api.model
|
||||
def _run_fifo(self, move, quantity=None):
|
||||
""" Value `move` according to the FIFO rule, meaning we consume the
|
||||
oldest receipt first. Candidates receipts are marked consumed or free
|
||||
thanks to their `remaining_qty` and `remaining_value` fields.
|
||||
By definition, `move` should be an outgoing stock move.
|
||||
|
||||
:param quantity: quantity to value instead of `move.product_qty`
|
||||
:returns: valued amount in absolute
|
||||
"""
|
||||
move.ensure_one()
|
||||
# Find back incoming stock moves (called candidates here) to value this move.
|
||||
|
||||
# Deal with possible move lines that do not impact the valuation.
|
||||
valued_move_lines = move.move_line_ids.filtered(lambda ml: ml.location_id._should_be_valued() and not ml.location_dest_id._should_be_valued() and not ml.owner_id)
|
||||
valued_quantity = 0
|
||||
for valued_move_line in valued_move_lines:
|
||||
valued_quantity += valued_move_line.product_uom_id._compute_quantity(valued_move_line.qty_done, move.product_id.uom_id)
|
||||
|
||||
# Find back incoming stock moves (called candidates here) to value this move.
|
||||
qty_to_take_on_candidates = quantity or valued_quantity
|
||||
candidates = move.product_id._get_fifo_candidates_in_move()
|
||||
new_standard_price = 0
|
||||
@@ -259,11 +273,12 @@ class StockMove(models.Model):
|
||||
elif qty_to_take_on_candidates > 0:
|
||||
last_fifo_price = new_standard_price or move.product_id.standard_price
|
||||
negative_stock_value = last_fifo_price * -qty_to_take_on_candidates
|
||||
tmp_value += abs(negative_stock_value)
|
||||
vals = {
|
||||
'remaining_qty': move.remaining_qty + -qty_to_take_on_candidates,
|
||||
'remaining_value': move.remaining_value + negative_stock_value,
|
||||
'value': -tmp_value + negative_stock_value,
|
||||
'price_unit': (-tmp_value + negative_stock_value) / (move.product_qty or quantity),
|
||||
'value': -tmp_value,
|
||||
'price_unit': -1 * last_fifo_price,
|
||||
}
|
||||
move.write(vals)
|
||||
return tmp_value
|
||||
@@ -388,12 +403,14 @@ class StockMove(models.Model):
|
||||
if not candidates:
|
||||
continue
|
||||
qty_to_take_on_candidates = abs(move.remaining_qty)
|
||||
qty_taken_on_candidates = 0
|
||||
tmp_value = 0
|
||||
for candidate in candidates:
|
||||
if candidate.remaining_qty <= qty_to_take_on_candidates:
|
||||
qty_taken_on_candidate = candidate.remaining_qty
|
||||
else:
|
||||
qty_taken_on_candidate = qty_to_take_on_candidates
|
||||
qty_taken_on_candidates += qty_taken_on_candidate
|
||||
|
||||
value_taken_on_candidate = qty_taken_on_candidate * candidate.price_unit
|
||||
candidate_vals = {
|
||||
@@ -407,27 +424,22 @@ class StockMove(models.Model):
|
||||
if qty_to_take_on_candidates == 0:
|
||||
break
|
||||
|
||||
remaining_value_before_vacuum = move.remaining_value
|
||||
|
||||
# If `remaining_qty` should be updated to 0, we wipe `remaining_value`. If it was set
|
||||
# it was only used to infer the correction entry anyway.
|
||||
new_remaining_qty = -qty_to_take_on_candidates
|
||||
new_remaining_value = 0 if not new_remaining_qty else move.remaining_value + tmp_value
|
||||
# When working with `price_unit`, beware that out move are negative.
|
||||
move_price_unit = move.price_unit if move._is_out() else -1 * move.price_unit
|
||||
# Get the estimated value we will correct.
|
||||
remaining_value_before_vacuum = qty_taken_on_candidates * move_price_unit
|
||||
new_remaining_qty = move.remaining_qty + qty_taken_on_candidates
|
||||
new_remaining_value = new_remaining_qty * abs(move.price_unit)
|
||||
|
||||
corrected_value = remaining_value_before_vacuum + tmp_value
|
||||
move.write({
|
||||
'remaining_value': new_remaining_value,
|
||||
'remaining_qty': new_remaining_qty,
|
||||
'value': move.value - corrected_value,
|
||||
})
|
||||
|
||||
if move.product_id.valuation == 'real_time':
|
||||
# If `move.remaining_value` is negative, it means that we initially valued this move at
|
||||
# an estimated price *and* posted an entry. `tmp_value` is the real value we took to
|
||||
# compensate and should always be positive, but if the remaining value is still negative
|
||||
# we have to take care to not overvalue by decreasing the correction entry by what's
|
||||
# already been posted.
|
||||
corrected_value = tmp_value
|
||||
if remaining_value_before_vacuum < 0:
|
||||
corrected_value += remaining_value_before_vacuum
|
||||
|
||||
# If `corrected_value` is 0, absolutely do *not* call `_account_entry_move`. We
|
||||
# force the amount in the context, but in the case it is 0 it'll create an entry
|
||||
# for the entire cost of the move. This case happens when the candidates moves
|
||||
@@ -441,9 +453,9 @@ class StockMove(models.Model):
|
||||
# The correction should behave as a return too. As `_account_entry_move`
|
||||
# will post the natural values for an IN move (credit IN account, debit
|
||||
# OUT one), we inverse the sign to create the correct entries.
|
||||
move.with_context(force_valuation_amount=-corrected_value)._account_entry_move()
|
||||
move.with_context(force_valuation_amount=-corrected_value, forced_quantity=0)._account_entry_move()
|
||||
else:
|
||||
move.with_context(force_valuation_amount=corrected_value)._account_entry_move()
|
||||
move.with_context(force_valuation_amount=corrected_value, forced_quantity=0)._account_entry_move()
|
||||
|
||||
@api.model
|
||||
def _run_fifo_vacuum(self):
|
||||
@@ -502,6 +514,11 @@ class StockMove(models.Model):
|
||||
else:
|
||||
valuation_amount = cost
|
||||
|
||||
if self._context.get('forced_ref'):
|
||||
ref = self._context['forced_ref']
|
||||
else:
|
||||
ref = self.picking_id.name
|
||||
|
||||
# the standard_price of the product may be in another decimal precision, or not compatible with the coinage of
|
||||
# the company currency... so we need to use round() before creating the accounting entries.
|
||||
debit_value = self.company_id.currency_id.round(valuation_amount)
|
||||
@@ -528,7 +545,7 @@ class StockMove(models.Model):
|
||||
'product_id': self.product_id.id,
|
||||
'quantity': qty,
|
||||
'product_uom_id': self.product_id.uom_id.id,
|
||||
'ref': self.picking_id.name,
|
||||
'ref': ref,
|
||||
'partner_id': partner_id,
|
||||
'debit': debit_value if debit_value > 0 else 0,
|
||||
'credit': -debit_value if debit_value < 0 else 0,
|
||||
@@ -539,7 +556,7 @@ class StockMove(models.Model):
|
||||
'product_id': self.product_id.id,
|
||||
'quantity': qty,
|
||||
'product_uom_id': self.product_id.uom_id.id,
|
||||
'ref': self.picking_id.name,
|
||||
'ref': ref,
|
||||
'partner_id': partner_id,
|
||||
'credit': credit_value if credit_value > 0 else 0,
|
||||
'debit': -credit_value if credit_value < 0 else 0,
|
||||
@@ -559,7 +576,7 @@ class StockMove(models.Model):
|
||||
'product_id': self.product_id.id,
|
||||
'quantity': qty,
|
||||
'product_uom_id': self.product_id.uom_id.id,
|
||||
'ref': self.picking_id.name,
|
||||
'ref': ref,
|
||||
'partner_id': partner_id,
|
||||
'credit': diff_amount > 0 and diff_amount or 0,
|
||||
'debit': diff_amount < 0 and -diff_amount or 0,
|
||||
@@ -571,14 +588,25 @@ class StockMove(models.Model):
|
||||
def _create_account_move_line(self, credit_account_id, debit_account_id, journal_id):
|
||||
self.ensure_one()
|
||||
AccountMove = self.env['account.move']
|
||||
move_lines = self._prepare_account_move_line(self.product_qty, abs(self.value), credit_account_id, debit_account_id)
|
||||
quantity = self.env.context.get('forced_quantity', self.product_qty if self._is_in() else -1 * self.product_qty)
|
||||
|
||||
# Make an informative `ref` on the created account move to differentiate between classic
|
||||
# movements, vacuum and edition of past moves.
|
||||
ref = self.picking_id.name
|
||||
if self.env.context.get('force_valuation_amount'):
|
||||
if self.env.context.get('forced_quantity') == 0:
|
||||
ref = 'Revaluation of %s (negative inventory)' % ref
|
||||
elif self.env.context.get('forced_quantity') is not None:
|
||||
ref = 'Correction of %s (modification of past move)' % ref
|
||||
|
||||
move_lines = self.with_context(forced_ref=ref)._prepare_account_move_line(quantity, abs(self.value), credit_account_id, debit_account_id)
|
||||
if move_lines:
|
||||
date = self._context.get('force_period_date', fields.Date.context_today(self))
|
||||
new_account_move = AccountMove.create({
|
||||
'journal_id': journal_id,
|
||||
'line_ids': move_lines,
|
||||
'date': date,
|
||||
'ref': self.picking_id.name,
|
||||
'ref': ref,
|
||||
'stock_move_id': self.id,
|
||||
})
|
||||
new_account_move.post()
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.fields import Date
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
@@ -115,6 +118,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 1)
|
||||
self.assertEqual(move1_valuation_aml.debit, 100)
|
||||
self.assertEqual(move1_valuation_aml.credit, 0)
|
||||
self.assertEqual(move1_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move1_valuation_aml.quantity, 10)
|
||||
self.assertEqual(move1_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
self.assertEqual(len(output_aml), 0)
|
||||
@@ -159,6 +165,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 2)
|
||||
self.assertEqual(move2_valuation_aml.debit, 80)
|
||||
self.assertEqual(move2_valuation_aml.credit, 0)
|
||||
self.assertEqual(move2_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move2_valuation_aml.quantity, 10)
|
||||
self.assertEqual(move2_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
self.assertEqual(len(output_aml), 0)
|
||||
@@ -207,6 +216,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 3)
|
||||
self.assertEqual(move3_valuation_aml.debit, 0)
|
||||
self.assertEqual(move3_valuation_aml.credit, 30)
|
||||
self.assertEqual(move3_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move3_valuation_aml.quantity, -3)
|
||||
self.assertEqual(move3_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
move3_output_aml = output_aml[-1]
|
||||
@@ -243,7 +255,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move1.product_uom_qty, 12.0)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 9.0)
|
||||
self.assertEqual(move1.value, 100.0)
|
||||
self.assertEqual(move1.value, 120.0) # move 1 is now 10@10 + 2@10
|
||||
self.assertEqual(move1.remaining_value, 90.0)
|
||||
|
||||
# account values for move1
|
||||
@@ -258,6 +270,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 4)
|
||||
self.assertEqual(move1_correction_valuation_aml.debit, 20)
|
||||
self.assertEqual(move1_correction_valuation_aml.credit, 0)
|
||||
self.assertEqual(move1_correction_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move1_correction_valuation_aml.quantity, 2)
|
||||
self.assertEqual(move1_correction_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
self.assertEqual(len(output_aml), 1)
|
||||
@@ -311,6 +326,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 5)
|
||||
self.assertEqual(move4_valuation_aml.debit, 0)
|
||||
self.assertEqual(move4_valuation_aml.credit, 90)
|
||||
self.assertEqual(move4_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move4_valuation_aml.quantity, -9)
|
||||
self.assertEqual(move4_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
move4_output_aml = output_aml[-1]
|
||||
@@ -326,7 +344,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move1.product_uom_qty, 12)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 0)
|
||||
self.assertEqual(move1.value, 100)
|
||||
self.assertEqual(move1.value, 120)
|
||||
self.assertEqual(move1.remaining_value, 0)
|
||||
self.assertEqual(move2.product_uom_qty, 10.0)
|
||||
self.assertEqual(move2.price_unit, 8.0)
|
||||
@@ -373,6 +391,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 6)
|
||||
self.assertEqual(move5_valuation_aml.debit, 0)
|
||||
self.assertEqual(move5_valuation_aml.credit, 160)
|
||||
self.assertEqual(move5_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move5_valuation_aml.quantity, -20)
|
||||
self.assertEqual(move5_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
move5_output_aml = output_aml[-1]
|
||||
@@ -388,7 +409,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move1.product_uom_qty, 12)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 0)
|
||||
self.assertEqual(move1.value, 100)
|
||||
self.assertEqual(move1.value, 120)
|
||||
self.assertEqual(move1.remaining_value, 0)
|
||||
self.assertEqual(move2.product_uom_qty, 10.0)
|
||||
self.assertEqual(move2.price_unit, 8.0)
|
||||
@@ -445,6 +466,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 7)
|
||||
self.assertEqual(move6_valuation_aml.debit, 120)
|
||||
self.assertEqual(move6_valuation_aml.credit, 0)
|
||||
self.assertEqual(move6_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move6_valuation_aml.quantity, 10)
|
||||
self.assertEqual(move6_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
self.assertEqual(len(output_aml), 3)
|
||||
@@ -457,7 +481,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move1.product_uom_qty, 12)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 0)
|
||||
self.assertEqual(move1.value, 100)
|
||||
self.assertEqual(move1.value, 120)
|
||||
self.assertEqual(move1.remaining_value, 0)
|
||||
self.assertEqual(move2.product_uom_qty, 10.0)
|
||||
self.assertEqual(move2.price_unit, 8.0)
|
||||
@@ -495,6 +519,9 @@ class TestStockValuation(TransactionCase):
|
||||
vacuum_valuation_aml = valuation_aml[-1]
|
||||
self.assertEqual(len(valuation_aml), 8)
|
||||
self.assertEqual(vacuum_valuation_aml.balance, -40)
|
||||
self.assertEqual(vacuum_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(vacuum_valuation_aml.quantity, 0)
|
||||
self.assertEqual(vacuum_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
vacuum_output_aml = output_aml[-1]
|
||||
@@ -505,7 +532,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move1.product_uom_qty, 12)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 0)
|
||||
self.assertEqual(move1.value, 100)
|
||||
self.assertEqual(move1.value, 120)
|
||||
self.assertEqual(move1.remaining_value, 0)
|
||||
self.assertEqual(move2.product_uom_qty, 10.0)
|
||||
self.assertEqual(move2.price_unit, 8.0)
|
||||
@@ -522,7 +549,11 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move4.remaining_value, 0)
|
||||
self.assertEqual(move5.product_uom_qty, 20.0)
|
||||
self.assertEqual(move5.remaining_qty, 0.0)
|
||||
self.assertEqual(move5.value, -160.0)
|
||||
|
||||
# move5 sent 10@8 and 10@estimated price of 8
|
||||
# the vacuum compensated the 10@8 by 12@10
|
||||
# -(10*8 + 10@12) = -200
|
||||
self.assertEqual(move5.value, -200.0)
|
||||
self.assertEqual(move5.remaining_value, 0.0)
|
||||
self.assertEqual(move6.product_uom_qty, 10)
|
||||
self.assertEqual(move6.price_unit, 12.0)
|
||||
@@ -553,7 +584,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move6.product_uom_qty, 8)
|
||||
self.assertEqual(move6.price_unit, 12)
|
||||
self.assertEqual(move6.remaining_qty, -2)
|
||||
self.assertEqual(move6.value, 120)
|
||||
self.assertEqual(move6.value, 96) # move6 is now 8@12
|
||||
self.assertEqual(move6.remaining_value, -24)
|
||||
|
||||
# account values for move1
|
||||
@@ -566,6 +597,9 @@ class TestStockValuation(TransactionCase):
|
||||
move6_correction_valuation_aml = valuation_aml[-1]
|
||||
self.assertEqual(move6_correction_valuation_aml.debit, 0)
|
||||
self.assertEqual(move6_correction_valuation_aml.credit, 24)
|
||||
self.assertEqual(move6_correction_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move6_correction_valuation_aml.quantity, -2)
|
||||
self.assertEqual(move6_correction_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
# link between stock move and account move
|
||||
self.assertEqual(len(move6.account_move_ids), 2)
|
||||
@@ -607,6 +641,9 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 10)
|
||||
self.assertEqual(move7_valuation_aml.debit, 60)
|
||||
self.assertEqual(move7_valuation_aml.credit, 0)
|
||||
self.assertEqual(move7_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move7_valuation_aml.quantity, 4)
|
||||
self.assertEqual(move7_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
# link between stock move and account move
|
||||
self.assertEqual(len(move7.account_move_ids), 1)
|
||||
@@ -629,12 +666,15 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(len(valuation_aml), 11)
|
||||
self.assertEqual(move6_correction2_valuation_aml.debit, 0)
|
||||
self.assertEqual(move6_correction2_valuation_aml.credit, 6)
|
||||
self.assertEqual(move6_correction2_valuation_aml.product_id.id, self.product1.id)
|
||||
self.assertEqual(move6_correction2_valuation_aml.quantity, 0)
|
||||
self.assertEqual(move6_correction_valuation_aml.product_uom_id.id, self.uom_unit.id)
|
||||
|
||||
# stock_account values
|
||||
self.assertEqual(move1.product_uom_qty, 12)
|
||||
self.assertEqual(move1.price_unit, 10.0)
|
||||
self.assertEqual(move1.remaining_qty, 0)
|
||||
self.assertEqual(move1.value, 100)
|
||||
self.assertEqual(move1.value, 120)
|
||||
self.assertEqual(move1.remaining_value, 0)
|
||||
self.assertEqual(move2.product_uom_qty, 10.0)
|
||||
self.assertEqual(move2.price_unit, 8.0)
|
||||
@@ -651,12 +691,12 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move4.remaining_value, 0)
|
||||
self.assertEqual(move5.product_uom_qty, 20.0)
|
||||
self.assertEqual(move5.remaining_qty, 0.0)
|
||||
self.assertEqual(move5.value, -160.0)
|
||||
self.assertEqual(move5.value, -200.0)
|
||||
self.assertEqual(move5.remaining_value, 0.0)
|
||||
self.assertEqual(move6.product_uom_qty, 8)
|
||||
self.assertEqual(move6.price_unit, 12.0)
|
||||
self.assertEqual(move6.remaining_qty, 0.0)
|
||||
self.assertEqual(move6.value, 120)
|
||||
self.assertEqual(move6.value, 90)
|
||||
self.assertEqual(move6.remaining_value, 0)
|
||||
self.assertEqual(move7.product_uom_qty, 4.0)
|
||||
self.assertEqual(move7.price_unit, 15.0)
|
||||
@@ -681,14 +721,28 @@ class TestStockValuation(TransactionCase):
|
||||
# ---------------------------------------------------------------------
|
||||
# Ending
|
||||
# ---------------------------------------------------------------------
|
||||
# check on remaining_qty
|
||||
self.assertEqual(self.product1.qty_available, 2)
|
||||
# check on remaining_value
|
||||
self.assertEqual(self.product1.stock_value, 30)
|
||||
# check on accounting entries
|
||||
self.assertEqual(sum(self._get_stock_input_move_lines().mapped('debit')), 30)
|
||||
self.assertEqual(sum(self._get_stock_input_move_lines().mapped('credit')), 380)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 380)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 350)
|
||||
self.assertEqual(sum(self._get_stock_output_move_lines().mapped('debit')), 320)
|
||||
self.assertEqual(sum(self._get_stock_output_move_lines().mapped('credit')), 0)
|
||||
moves = move1 + move2 + move3 + move4 + move5 + move6 + move7
|
||||
# check on value
|
||||
self.assertEqual(sum(moves.mapped('value')), 30)
|
||||
# check on product_qty
|
||||
qty = 0
|
||||
for move in moves:
|
||||
if move._is_in():
|
||||
qty += move.product_qty
|
||||
else:
|
||||
qty -= move.product_qty
|
||||
self.assertEqual(qty, 2)
|
||||
|
||||
def test_fifo_perpetual_2(self):
|
||||
# http://accountingexplained.com/financial/inventories/fifo-method
|
||||
@@ -1224,8 +1278,8 @@ class TestStockValuation(TransactionCase):
|
||||
self.env['stock.move']._run_fifo_vacuum()
|
||||
|
||||
# stock values for move1 and move2
|
||||
self.assertEqual(move1.value, -400.0)
|
||||
self.assertEqual(move1.remaining_value, 200.0)
|
||||
self.assertEqual(move1.value, -680.0) # 40@15 + 10@8
|
||||
self.assertEqual(move1.remaining_value, -80.0)
|
||||
self.assertEqual(move1.remaining_qty, -10.0)
|
||||
self.assertEqual(move2.value, 600.0)
|
||||
self.assertEqual(move2.remaining_value, 0.0)
|
||||
@@ -1235,14 +1289,13 @@ class TestStockValuation(TransactionCase):
|
||||
valuation_aml = self._get_stock_valuation_move_lines()
|
||||
vacuum1_valuation_aml = valuation_aml[-1]
|
||||
self.assertEqual(vacuum1_valuation_aml.debit, 0)
|
||||
# 200 was credited more in valuation (we initially credited 400 but the vacuum realized
|
||||
# that 600 was the right value)
|
||||
self.assertEqual(vacuum1_valuation_aml.credit, 200)
|
||||
# 280 was credited more in valuation (we compensated 40 items here, so initially 40 were
|
||||
# valued at 8 -> 320 in credit but now we actually sent 40@15 = 600, so the difference is
|
||||
# 280 more credited)
|
||||
self.assertEqual(vacuum1_valuation_aml.credit, 280)
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
vacuum1_output_aml = output_aml[-1]
|
||||
# 200 was debited more in output (we initially debited 400 but the vacuum realized
|
||||
# that 600 was the right value)
|
||||
self.assertEqual(vacuum1_output_aml.debit, 200)
|
||||
self.assertEqual(vacuum1_output_aml.debit, 280)
|
||||
self.assertEqual(vacuum1_output_aml.credit, 0)
|
||||
|
||||
self.assertTrue(set(move1.mapped('account_move_ids.line_ids').ids) == {move1_valuation_aml.id, move1_output_aml.id, vacuum1_valuation_aml.id, vacuum1_output_aml.id})
|
||||
@@ -1290,7 +1343,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.env['stock.move']._run_fifo_vacuum()
|
||||
|
||||
# stock values for move1-3
|
||||
self.assertEqual(move1.value, -400.0)
|
||||
self.assertEqual(move1.value, -850.0) # 40@15 + 10@25
|
||||
self.assertEqual(move1.remaining_value, 0.0)
|
||||
self.assertEqual(move1.remaining_qty, 0.0)
|
||||
self.assertEqual(move2.value, 600.0)
|
||||
@@ -1304,14 +1357,11 @@ class TestStockValuation(TransactionCase):
|
||||
valuation_aml = self._get_stock_valuation_move_lines()
|
||||
vacuum2_valuation_aml = valuation_aml[-1]
|
||||
self.assertEqual(vacuum2_valuation_aml.debit, 0)
|
||||
# 250 was credited more in valuation (we initially credited 400+200 but the vacuum realized
|
||||
# that 850 was the right value)
|
||||
self.assertEqual(vacuum2_valuation_aml.credit, 250)
|
||||
# there is still 10@8 to compensate with 10@25 -> 170 to credit more in the valuation account
|
||||
self.assertEqual(vacuum2_valuation_aml.credit, 170)
|
||||
output_aml = self._get_stock_output_move_lines()
|
||||
vacuum2_output_aml = output_aml[-1]
|
||||
# 250 was debited more in output (we initially debited 400+200 but the vacuum realized
|
||||
# that 850 was the right value)
|
||||
self.assertEqual(vacuum2_output_aml.debit, 250)
|
||||
self.assertEqual(vacuum2_output_aml.debit, 170)
|
||||
self.assertEqual(vacuum2_output_aml.credit, 0)
|
||||
|
||||
self.assertTrue(set(move1.mapped('account_move_ids.line_ids').ids) == {move1_valuation_aml.id, move1_output_aml.id, vacuum1_valuation_aml.id, vacuum1_output_aml.id, vacuum2_valuation_aml.id, vacuum2_output_aml.id})
|
||||
@@ -1655,6 +1705,18 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(sum(self._get_stock_output_move_lines().mapped('credit')), 0)
|
||||
|
||||
def test_fifo_add_move_in_done_picking_1(self):
|
||||
""" The flow is:
|
||||
|
||||
product2 std price = 20
|
||||
IN01 10@10 product1
|
||||
IN01 10@20 product2
|
||||
IN01 correction 10@20 -> 11@20 (product2)
|
||||
DO01 11 product2
|
||||
DO02 1 product2
|
||||
DO02 correction 1 -> 2 (negative stock)
|
||||
IN03 2@30 product2
|
||||
vacuum
|
||||
"""
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
@@ -1725,16 +1787,21 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(self.product2.qty_available, 10)
|
||||
self.assertEqual(self.product2.stock_value, 200)
|
||||
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 300)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 0)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Edit the previous stock move, receive 11
|
||||
# ---------------------------------------------------------------------
|
||||
move2.quantity_done = 11
|
||||
|
||||
self.assertEqual(move2.value, 200.0)
|
||||
self.assertEqual(move2.value, 220.0) # after correction, the move should be valued at 11@20
|
||||
self.assertEqual(move2.remaining_qty, 11.0)
|
||||
self.assertEqual(move2.price_unit, 20.0)
|
||||
self.assertEqual(move2.remaining_value, 220.0)
|
||||
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 320)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 0)
|
||||
# ---------------------------------------------------------------------
|
||||
# Send 11 product 2
|
||||
# ---------------------------------------------------------------------
|
||||
@@ -1768,9 +1835,13 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move3.remaining_qty, 0.0)
|
||||
self.assertEqual(move3.price_unit, -20.0)
|
||||
self.assertEqual(move3.remaining_value, 0.0)
|
||||
self.assertEqual(self.product2.qty_available, 0)
|
||||
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 320)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 220)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Add one move of product 2
|
||||
# Add one move of product 2, this'll make some negative stock.
|
||||
# ---------------------------------------------------------------------
|
||||
move4 = self.env['stock.move'].create({
|
||||
'picking_id': delivery.id,
|
||||
@@ -1794,12 +1865,18 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(move4.price_unit, -20.0)
|
||||
self.assertEqual(move4.remaining_value, -20.0)
|
||||
|
||||
self.assertEqual(self.product2.qty_available, -1)
|
||||
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 320)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 240)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# edit the created move, add 1
|
||||
# ---------------------------------------------------------------------
|
||||
move4.quantity_done = 2
|
||||
|
||||
self.assertEqual(move4.value, -20.0)
|
||||
self.assertEqual(self.product2.qty_available, -2)
|
||||
self.assertEqual(move4.value, -40.0)
|
||||
self.assertEqual(move4.remaining_qty, -2.0)
|
||||
self.assertEqual(move4.price_unit, -20.0)
|
||||
self.assertEqual(move4.remaining_value, -40.0)
|
||||
@@ -1823,7 +1900,7 @@ class TestStockValuation(TransactionCase):
|
||||
# ---------------------------------------------------------------------
|
||||
# receive 2 products 2 @ 30
|
||||
# ---------------------------------------------------------------------
|
||||
move1 = self.env['stock.move'].create({
|
||||
move5 = self.env['stock.move'].create({
|
||||
'picking_id': receipt.id,
|
||||
'name': '10 in',
|
||||
'location_id': self.supplier_location.id,
|
||||
@@ -1840,8 +1917,11 @@ class TestStockValuation(TransactionCase):
|
||||
'qty_done': 2.0,
|
||||
})]
|
||||
})
|
||||
move1._action_confirm()
|
||||
move1._action_done()
|
||||
move5._action_confirm()
|
||||
move5._action_done()
|
||||
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('debit')), 380)
|
||||
self.assertEqual(sum(self._get_stock_valuation_move_lines().mapped('credit')), 260)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# run vacuum
|
||||
@@ -1858,6 +1938,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(self.product2.qty_available, 0)
|
||||
self.assertEqual(self.product2.stock_value, 0)
|
||||
self.assertEqual(move4.remaining_value, 0)
|
||||
self.assertEqual(move4.value, -60) # after correction, the move is valued -(2*30)
|
||||
|
||||
def test_fifo_add_moveline_in_done_move_1(self):
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
@@ -1921,7 +2002,7 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(sum(self._get_stock_output_move_lines().mapped('credit')), 0)
|
||||
|
||||
def test_fifo_edit_done_move1(self):
|
||||
""" Check that incrementing the done quantity will correctly re-run a fifo lookup.
|
||||
""" Increase OUT done move while quantities are available.
|
||||
"""
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
|
||||
@@ -2059,6 +2140,9 @@ class TestStockValuation(TransactionCase):
|
||||
# ---------------------------------------------------------------------
|
||||
move3.quantity_done = 14
|
||||
self.assertEqual(move3.product_qty, 14)
|
||||
# old value: -80 -(8@10)
|
||||
# new value: -148 => -(10@10 + 4@12)
|
||||
self.assertEqual(move3.value, -148)
|
||||
|
||||
# older move
|
||||
self.assertEqual(move1.remaining_value, 0) # before, 20
|
||||
@@ -2090,6 +2174,8 @@ class TestStockValuation(TransactionCase):
|
||||
self.assertEqual(sum(self._get_stock_output_move_lines().mapped('credit')), 0)
|
||||
|
||||
def test_fifo_edit_done_move2(self):
|
||||
""" Decrease, then increase OUT done move while quantities are available.
|
||||
"""
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
@@ -2152,7 +2238,7 @@ class TestStockValuation(TransactionCase):
|
||||
# ---------------------------------------------------------------------
|
||||
move2.quantity_done = 8
|
||||
|
||||
self.assertEqual(move2.value, -100.0)
|
||||
self.assertEqual(move2.value, -80.0) # the move actually sent 8@10
|
||||
self.assertEqual(move2.remaining_qty, 0.0)
|
||||
self.assertEqual(move2.remaining_value, 0.0)
|
||||
|
||||
@@ -2167,7 +2253,7 @@ class TestStockValuation(TransactionCase):
|
||||
# ---------------------------------------------------------------------
|
||||
move2.with_context(debug=True).quantity_done = 10
|
||||
|
||||
self.assertEqual(move2.value, -100.0)
|
||||
self.assertEqual(move2.value, -100.0) # the move actually sent 10@10
|
||||
self.assertEqual(move2.remaining_qty, 0.0)
|
||||
self.assertEqual(move2.remaining_value, 0.0)
|
||||
|
||||
@@ -3002,3 +3088,479 @@ class TestStockValuation(TransactionCase):
|
||||
with self.assertRaises(UserError):
|
||||
move2._action_done()
|
||||
|
||||
def test_at_date_standard_1(self):
|
||||
self.product1.product_tmpl_id.cost_method = 'standard'
|
||||
|
||||
now = Date.from_string(Date.today())
|
||||
date1 = now - timedelta(days=8)
|
||||
date2 = now - timedelta(days=7)
|
||||
date3 = now - timedelta(days=6)
|
||||
date4 = now - timedelta(days=5)
|
||||
date5 = now - timedelta(days=4)
|
||||
date6 = now - timedelta(days=3)
|
||||
date7 = now - timedelta(days=2)
|
||||
date8 = now - timedelta(days=1)
|
||||
|
||||
# set the standard price to 10
|
||||
self.product1.product_tmpl_id.standard_price = 10
|
||||
self.env['product.price.history'].search([('product_id', '=', self.product1.id)], order='datetime desc, id DESC', limit=1).datetime = date1
|
||||
|
||||
# receive 10
|
||||
move1 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
})
|
||||
move1._action_confirm()
|
||||
move1._action_assign()
|
||||
move1.move_line_ids.qty_done = 10
|
||||
move1._action_done()
|
||||
move1.date = date2
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
# receive 20
|
||||
move2 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 20,
|
||||
})
|
||||
move2._action_confirm()
|
||||
move2._action_assign()
|
||||
move2.move_line_ids.qty_done = 20
|
||||
move2._action_done()
|
||||
move2.date = date3
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 30)
|
||||
self.assertEqual(self.product1.stock_value, 300)
|
||||
|
||||
# send 15
|
||||
move3 = self.env['stock.move'].create({
|
||||
'name': 'out 10',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 15,
|
||||
})
|
||||
move3._action_confirm()
|
||||
move3._action_assign()
|
||||
move3.move_line_ids.qty_done = 15
|
||||
move3._action_done()
|
||||
move3.date = date4
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 15)
|
||||
self.assertEqual(self.product1.stock_value, 150)
|
||||
|
||||
# set the standard price to 5
|
||||
self.product1.product_tmpl_id.standard_price = 5
|
||||
self.env['product.price.history'].search([('product_id', '=', self.product1.id)], order='datetime desc, id DESC', limit=1).datetime = date5
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 15)
|
||||
self.assertEqual(self.product1.stock_value, 75)
|
||||
|
||||
# send 20
|
||||
move4 = self.env['stock.move'].create({
|
||||
'name': 'out 10',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 20,
|
||||
})
|
||||
move4._action_confirm()
|
||||
move4._action_assign()
|
||||
move4.move_line_ids.qty_done = 20
|
||||
move4._action_done()
|
||||
move4.date = date6
|
||||
|
||||
self.assertEqual(self.product1.qty_available, -5)
|
||||
self.assertEqual(self.product1.stock_value, -25)
|
||||
|
||||
# set the standard price to 7.5
|
||||
self.product1.product_tmpl_id.standard_price = 7.5
|
||||
self.env['product.price.history'].search([('product_id', '=', self.product1.id)], order='datetime desc, id DESC', limit=1).datetime = date7
|
||||
|
||||
# receive 100
|
||||
move5 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 100,
|
||||
})
|
||||
move5._action_confirm()
|
||||
move5._action_assign()
|
||||
move5.move_line_ids.qty_done = 100
|
||||
move5._action_done()
|
||||
move5.date = date8
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 95)
|
||||
self.assertEqual(self.product1.stock_value, 712.5)
|
||||
|
||||
# Quantity at date
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_available, 0)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_available, 30)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_available, 15)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_available, 15)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_available, -5)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date7)).qty_available, -5)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date8)).qty_available, 95)
|
||||
|
||||
# Valuation at date
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 100)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).stock_value, 300)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).stock_value, 150)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).stock_value, 75)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -25)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date8)).stock_value, 712.5)
|
||||
|
||||
# edit the done quantity of move1, decrease it
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 10)
|
||||
move1.quantity_done = 5
|
||||
|
||||
# the quantity at date will reflect the change directly
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_available, 5)
|
||||
|
||||
# as when we decrease a quantity on a recreipt, we consider it as a out move with the price
|
||||
# of today, the value will be decrease of 100 - (5*7.5)
|
||||
self.assertEqual(move1.value, 62.5)
|
||||
|
||||
# the valuatin at date will take the qty at date * the standard price at date, that's why
|
||||
# it is different.
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 50)
|
||||
|
||||
# edit move 4, send 15 instead of 20
|
||||
# we now have +5 + 20 - 15 -20 = -10 * a standard price of 5
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -50)
|
||||
move4.quantity_done = 15
|
||||
|
||||
# -(20*5) + (5*7.5)
|
||||
self.assertEqual(move4.value, -62.5)
|
||||
# we now have +5 + 20 - 15 -15 = -5 * a standard price of 5
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, -25)
|
||||
|
||||
def test_at_date_fifo_1(self):
|
||||
""" Make some operations at different dates, check that the results of the valuation at
|
||||
date wizard are consistent. Afterwards, edit the done quantity of some operations. The
|
||||
valuation at date results should take these changes into account.
|
||||
"""
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
|
||||
now = Date.from_string(Date.today())
|
||||
date1 = now - timedelta(days=8)
|
||||
date2 = now - timedelta(days=7)
|
||||
date3 = now - timedelta(days=6)
|
||||
date4 = now - timedelta(days=5)
|
||||
date5 = now - timedelta(days=4)
|
||||
date6 = now - timedelta(days=3)
|
||||
|
||||
# receive 10@10
|
||||
move1 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 10,
|
||||
})
|
||||
move1._action_confirm()
|
||||
move1._action_assign()
|
||||
move1.move_line_ids.qty_done = 10
|
||||
move1._action_done()
|
||||
move1.date = date1
|
||||
move1.account_move_ids.write({'date': date1})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
# receive 10@12
|
||||
move2 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 12,
|
||||
})
|
||||
move2._action_confirm()
|
||||
move2._action_assign()
|
||||
move2.move_line_ids.qty_done = 10
|
||||
move2._action_done()
|
||||
move2.date = date2
|
||||
move2.account_move_ids.write({'date': date2})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 20)
|
||||
self.assertEqual(self.product1.stock_value, 220)
|
||||
|
||||
# send 15
|
||||
move3 = self.env['stock.move'].create({
|
||||
'name': 'out 10',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 15,
|
||||
})
|
||||
move3._action_confirm()
|
||||
move3._action_assign()
|
||||
move3.move_line_ids.qty_done = 15
|
||||
move3._action_done()
|
||||
move3.date = date3
|
||||
move3.account_move_ids.write({'date': date3})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 5)
|
||||
self.assertEqual(self.product1.stock_value, 60)
|
||||
|
||||
# send 20
|
||||
move4 = self.env['stock.move'].create({
|
||||
'name': 'out 10',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 20,
|
||||
})
|
||||
move4._action_confirm()
|
||||
move4._action_assign()
|
||||
move4.move_line_ids.qty_done = 20
|
||||
move4._action_done()
|
||||
move4.date = date4
|
||||
move4.account_move_ids.write({'date': date4})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, -15)
|
||||
self.assertEqual(self.product1.stock_value, -180)
|
||||
|
||||
# receive 100@15
|
||||
move5 = self.env['stock.move'].create({
|
||||
'name': 'in 10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 100,
|
||||
'price_unit': 15,
|
||||
})
|
||||
move5._action_confirm()
|
||||
move5._action_assign()
|
||||
move5.move_line_ids.qty_done = 100
|
||||
move5._action_done()
|
||||
move5.date = date5
|
||||
move5.account_move_ids.write({'date': date5})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 85)
|
||||
self.assertEqual(self.product1.stock_value, 1320)
|
||||
|
||||
# run the vacuum to compensate the negative stock move
|
||||
self.env['stock.move']._run_fifo_vacuum()
|
||||
move4.account_move_ids[0].write({'date': date6})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 85)
|
||||
self.assertEqual(self.product1.stock_value, 1275)
|
||||
|
||||
# Edit the quantity done of move1, increase it.
|
||||
move1.quantity_done = 20
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# ending: manual valuation
|
||||
# ---------------------------------------------------------------------
|
||||
self.product1.product_tmpl_id.valuation = 'manual_periodic'
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_at_date, 20)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).stock_value, 200)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 30)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 320)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_at_date, 15)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).stock_value, 160)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_at_date, -5)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).stock_value, -125)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_at_date, 95)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).stock_value, 1375)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, 95)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, 1375)
|
||||
self.assertEqual(self.product1.qty_at_date, 95)
|
||||
self.assertEqual(self.product1.stock_value, 1375)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# ending: perpetual valuation
|
||||
# ---------------------------------------------------------------------
|
||||
self.product1.product_tmpl_id.valuation = 'real_time'
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).stock_value, 100)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 20)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 220)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_at_date, 5)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).stock_value, 60)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_at_date, -15)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).stock_value, -180)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_at_date, 85)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).stock_value, 1320)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, 85)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, 1275)
|
||||
self.assertEqual(self.product1.qty_at_date, 95)
|
||||
self.assertEqual(self.product1.stock_value, 1375)
|
||||
|
||||
def test_at_date_fifo_2(self):
|
||||
self.product1.product_tmpl_id.cost_method = 'fifo'
|
||||
|
||||
now = Date.from_string(Date.today())
|
||||
date1 = now - timedelta(days=8)
|
||||
date2 = now - timedelta(days=7)
|
||||
date3 = now - timedelta(days=6)
|
||||
date4 = now - timedelta(days=5)
|
||||
date5 = now - timedelta(days=4)
|
||||
date6 = now - timedelta(days=3)
|
||||
|
||||
# receive 10@10
|
||||
move1 = self.env['stock.move'].create({
|
||||
'name': 'in 10@10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 10,
|
||||
})
|
||||
move1._action_confirm()
|
||||
move1._action_assign()
|
||||
move1.move_line_ids.qty_done = 10
|
||||
move1._action_done()
|
||||
move1.date = date1
|
||||
move1.account_move_ids.write({'date': date1})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
# receive 10@15
|
||||
move2 = self.env['stock.move'].create({
|
||||
'name': 'in 10@15',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 15,
|
||||
})
|
||||
move2._action_confirm()
|
||||
move2._action_assign()
|
||||
move2.move_line_ids.qty_done = 10
|
||||
move2._action_done()
|
||||
move2.date = date2
|
||||
move2.account_move_ids.write({'date': date2})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 20)
|
||||
self.assertEqual(self.product1.stock_value, 250)
|
||||
|
||||
# send 30
|
||||
move3 = self.env['stock.move'].create({
|
||||
'name': 'out 30',
|
||||
'location_id': self.stock_location.id,
|
||||
'location_dest_id': self.customer_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 30,
|
||||
})
|
||||
move3._action_confirm()
|
||||
move3._action_assign()
|
||||
move3.move_line_ids.qty_done = 30
|
||||
move3._action_done()
|
||||
move3.date = date3
|
||||
move3.account_move_ids.write({'date': date3})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, -10)
|
||||
self.assertEqual(self.product1.stock_value, -150)
|
||||
|
||||
# receive 10@20
|
||||
move4 = self.env['stock.move'].create({
|
||||
'name': 'in 10@20',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 20,
|
||||
})
|
||||
move4._action_confirm()
|
||||
move4._action_assign()
|
||||
move4.move_line_ids.qty_done = 10
|
||||
move4._action_done()
|
||||
move4.date = date4
|
||||
move4.account_move_ids.write({'date': date4})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 0)
|
||||
self.assertEqual(self.product1.stock_value, 50)
|
||||
|
||||
# receive 10@10
|
||||
move5 = self.env['stock.move'].create({
|
||||
'name': 'in 10@10',
|
||||
'location_id': self.supplier_location.id,
|
||||
'location_dest_id': self.stock_location.id,
|
||||
'product_id': self.product1.id,
|
||||
'product_uom': self.uom_unit.id,
|
||||
'product_uom_qty': 10,
|
||||
'price_unit': 10,
|
||||
})
|
||||
move5._action_confirm()
|
||||
move5._action_assign()
|
||||
move5.move_line_ids.qty_done = 10
|
||||
move5._action_done()
|
||||
move5.date = date5
|
||||
move5.account_move_ids.write({'date': date5})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 10)
|
||||
self.assertEqual(self.product1.stock_value, 150)
|
||||
|
||||
# run the vacuum to compensate the negative stock move
|
||||
self.env['stock.move']._run_fifo_vacuum()
|
||||
move3.account_move_ids[0].write({'date': date6})
|
||||
|
||||
self.assertEqual(self.product1.qty_available, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# ending: manual valuation
|
||||
# ---------------------------------------------------------------------
|
||||
self.product1.product_tmpl_id.valuation = 'manual_periodic'
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).stock_value, 100)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 20)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 250)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_at_date, -10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).stock_value, -200)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_at_date, 0)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).stock_value, 0)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).stock_value, 100)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, 100)
|
||||
self.assertEqual(self.product1.qty_at_date, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# ending: perpetual valuation
|
||||
# ---------------------------------------------------------------------
|
||||
self.product1.product_tmpl_id.valuation = 'real_time'
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date1)).stock_value, 100)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).qty_at_date, 20)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date2)).stock_value, 250)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).qty_at_date, -10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date3)).stock_value, -150)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).qty_at_date, 0)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date4)).stock_value, 50)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date5)).stock_value, 150)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).qty_at_date, 10)
|
||||
self.assertEqual(self.product1.with_context(to_date=Date.to_string(date6)).stock_value, 100)
|
||||
self.assertEqual(self.product1.qty_at_date, 10)
|
||||
self.assertEqual(self.product1.stock_value, 100)
|
||||
|
||||
@@ -86,27 +86,14 @@
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_valuation_tree" model="ir.ui.view">
|
||||
<field name="name">product.valuation.tree</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="display_name" string="Product"/>
|
||||
<field name="qty_available" context="{'company_owned': True}" string="Quantity on Hand"/>
|
||||
<field name="uom_id" groups="product.group_uom"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="stock_value" sum="Stock Valuation" widget="monetary" string="Total Value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_valuation_action" model="ir.actions.act_window">
|
||||
<field name="name">Product Valuation</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">product.product</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="product_valuation_tree"/>
|
||||
<field name="view_id" ref="view_stock_product_tree2"/>
|
||||
<field name="domain">[('type', '=', 'product'), ('qty_available', '!=', 0)]</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="help" type="html">
|
||||
@@ -117,68 +104,5 @@
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_valuation_form_view" model="ir.ui.view">
|
||||
<field name="name">product.product</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_view_stock_move_lines']" position="after">
|
||||
<button string="Inventory Valuation" type="object" name="action_open_product_moves" class="oe_stat_button" icon="fa-cubes" attrs="{'invisible': ['|', ('cost_method', '=', 'standard'), ('id', '=', False)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_template_valuation_form_view" model="ir.ui.view">
|
||||
<field name="name">product.template</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="stock.product_template_form_view_procurement_button"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_view_stock_move_lines']" position="after">
|
||||
<button string="Inventory Valuation" type="object" name="action_open_product_moves" class="oe_stat_button" icon="fa-cubes" attrs="{'invisible': [('cost_method', '=', 'standard')]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- stock move valuation view -->
|
||||
<record id="view_move_tree_valuation" model="ir.ui.view">
|
||||
<field name="name">stock.move.tree.valuation</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field eval="8" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-muted="state == 'cancel'" decoration-danger="(state not in ('cancel','done')) and date > current_date" string="Moves" create="0">
|
||||
<field name="name"/>
|
||||
<field name="picking_id" string="Reference"/>
|
||||
<field name="origin"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="create_date" invisible="1" groups="base.group_no_one"/>
|
||||
<field name="product_id"/>
|
||||
<field name="location_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_dest_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="date" groups="base.group_no_one"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_uom_qty" string="Qty"/>
|
||||
<field name="product_uom" options="{'no_open': True, 'no_create': True}" string="Unit of Measure" groups="product.group_uom"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="value" sum="Stock Valuation"/>
|
||||
<field name="remaining_qty" invisible="context.get('is_avg')"/>
|
||||
<field name="remaining_value" sum="Stock Valuation" invisible="context.get('is_avg')"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="stock_move_valuation_action" model="ir.actions.act_window">
|
||||
<field name="name">Stock Moves</field>
|
||||
<field name="res_model">stock.move</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_move_tree_valuation"/>
|
||||
<field name="search_view_id" ref="stock.view_move_search"/>
|
||||
<field name="context">{'search_default_outgoing': 1, 'search_default_incoming': 1, 'search_default_done': 1, 'search_default_group_by_product': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new stock movement
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -44,11 +44,87 @@
|
||||
<field name="model">stock.return.picking</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='product_return_moves']/tree" position="inside">
|
||||
<field name="to_refund"/>
|
||||
<field name="to_refund" widget="boolean_toggle"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_valuation" name="Inventory Valuation" parent="stock.menu_warehouse_report" sequence="110" action="stock_account.action_stock_account_valuation_report"/>
|
||||
<!-- valuation wizard: current or at date -->
|
||||
<record id="view_stock_quantity_history" model="ir.ui.view">
|
||||
<field name="name">Valuation Report</field>
|
||||
<field name="model">stock.quantity.history</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Choose your date">
|
||||
<group>
|
||||
<group>
|
||||
<field name="compute_at_date" widget="radio"/>
|
||||
<field name="date" attrs="{'invisible': [('compute_at_date', '=', 0)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="open_table" string="Retrieve the inventory valuation" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_stock_product_tree2" model="ir.ui.view">
|
||||
<field name="name">product.stock.tree.2</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="qty_at_date"/>
|
||||
<field name="uom_id" groups="product.group_uom"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="stock_value" sum="Stock Valuation" widget="monetary"/>
|
||||
<field name="cost_method" invisible="1"/>
|
||||
<button name="action_valuation_at_date_details" type="object" icon="fa-info-circle" attrs="{'invisible': [('cost_method', '!=', 'fifo')]}" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_stock_inventory_valuation" model="ir.actions.act_window">
|
||||
<field name="name">Valuation Report</field>
|
||||
<field name="res_model">stock.quantity.history</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="stock_account.view_stock_quantity_history"/>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_compute_at_date': 0, 'valuation': True}</field>
|
||||
</record>
|
||||
<menuitem id="menu_valuation" name="Inventory Valuation" parent="stock.menu_warehouse_report" sequence="110" action="action_stock_inventory_valuation"/>
|
||||
|
||||
<!-- AML specialized tree view -->
|
||||
<record id="view_stock_account_aml" model="ir.ui.view">
|
||||
<field name="name">stock.account.aml</field>
|
||||
<field name="model">account.move.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="date" />
|
||||
<field name="ref" />
|
||||
<field name="product_id" />
|
||||
<field name="quantity" />
|
||||
<field name="product_uom_id" groups="product.group_uom" />
|
||||
<field name="balance" string="Value"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- stock move specialized tree view -->
|
||||
<record id="view_move_tree_valuation_at_date" model="ir.ui.view">
|
||||
<field name="name">stock.move.tree.valuation.at.date</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="date" />
|
||||
<field name="picking_id" string="Reference"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_id"/>
|
||||
<field name="product_uom_qty" string="Quantity"/>
|
||||
<field name="product_uom" options="{'no_open': True, 'no_create': True}" string="Unit of Measure" groups="product.group_uom"/>
|
||||
<field name="value" sum="Stock Valuation"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import stock_change_standard_price
|
||||
from . import stock_quantity_history
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, _
|
||||
|
||||
|
||||
class StockQuantityHistory(models.TransientModel):
|
||||
_inherit = 'stock.quantity.history'
|
||||
|
||||
def open_table(self):
|
||||
if not self.env.context.get('valuation'):
|
||||
return super(StockQuantityHistory, self).open_table()
|
||||
|
||||
self.env['stock.move']._run_fifo_vacuum()
|
||||
|
||||
if self.compute_at_date:
|
||||
tree_view_id = self.env.ref('stock_account.view_stock_product_tree2').id
|
||||
form_view_id = self.env.ref('stock.product_form_view_procurement_button').id
|
||||
# We pass `to_date` in the context so that `qty_available` will be computed across
|
||||
# moves until date.
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'views': [(tree_view_id, 'tree'), (form_view_id, 'form')],
|
||||
'view_mode': 'tree,form',
|
||||
'name': _('Products'),
|
||||
'res_model': 'product.product',
|
||||
'domain': "[('type', '=', 'product'), ('qty_available', '!=', 0)]",
|
||||
'context': dict(self.env.context, to_date=self.date),
|
||||
}
|
||||
return action
|
||||
else:
|
||||
return self.env.ref('stock_account.product_valuation_action').read()[0]
|
||||
|
||||
@@ -91,11 +91,13 @@ class LandedCost(models.Model):
|
||||
raise UserError(_('Cost and adjustments lines do not match. You should maybe recompute the landed costs.'))
|
||||
|
||||
for cost in self:
|
||||
move = self.env['account.move'].create({
|
||||
move = self.env['account.move']
|
||||
move_vals = {
|
||||
'journal_id': cost.account_journal_id.id,
|
||||
'date': cost.date,
|
||||
'ref': cost.name
|
||||
})
|
||||
'ref': cost.name,
|
||||
'line_ids': [],
|
||||
}
|
||||
for line in cost.valuation_adjustment_lines.filtered(lambda line: line.move_id):
|
||||
# Prorate the value at what's still in stock
|
||||
cost_to_add = (line.move_id.remaining_qty / line.move_id.product_qty) * line.additional_landed_cost
|
||||
@@ -103,6 +105,7 @@ class LandedCost(models.Model):
|
||||
new_landed_cost_value = line.move_id.landed_cost_value + line.additional_landed_cost
|
||||
line.move_id.write({
|
||||
'landed_cost_value': new_landed_cost_value,
|
||||
'value': line.move_id.value + cost_to_add,
|
||||
'remaining_value': line.move_id.remaining_value + cost_to_add,
|
||||
'price_unit': (line.move_id.value + new_landed_cost_value) / line.move_id.product_qty,
|
||||
})
|
||||
@@ -113,9 +116,9 @@ class LandedCost(models.Model):
|
||||
qty_out = line.move_id.product_qty - line.move_id.remaining_qty
|
||||
elif line.move_id._is_out():
|
||||
qty_out = line.move_id.product_qty
|
||||
line._create_accounting_entries(move, qty_out)
|
||||
|
||||
move.assert_balanced()
|
||||
move_vals['line_ids'] += line._create_accounting_entries(move, qty_out)
|
||||
|
||||
move = move.create(move_vals)
|
||||
cost.write({'state': 'done', 'account_move_id': move.id})
|
||||
move.post()
|
||||
return True
|
||||
@@ -315,13 +318,12 @@ class AdjustmentLines(models.Model):
|
||||
Generate the account.move.line values to track the landed cost.
|
||||
Afterwards, for the goods that are already out of stock, we should create the out moves
|
||||
"""
|
||||
AccountMoveLine = self.env['account.move.line'].with_context(check_move_validity=False, recompute=False)
|
||||
AccountMoveLine = []
|
||||
|
||||
base_line = {
|
||||
'name': self.name,
|
||||
'move_id': move.id,
|
||||
'product_id': self.product_id.id,
|
||||
'quantity': self.quantity,
|
||||
'quantity': 0,
|
||||
}
|
||||
debit_line = dict(base_line, account_id=debit_account_id)
|
||||
credit_line = dict(base_line, account_id=credit_account_id)
|
||||
@@ -333,18 +335,18 @@ class AdjustmentLines(models.Model):
|
||||
# negative cost, reverse the entry
|
||||
debit_line['credit'] = -diff
|
||||
credit_line['debit'] = -diff
|
||||
AccountMoveLine.create(debit_line)
|
||||
AccountMoveLine.create(credit_line)
|
||||
AccountMoveLine.append([0, 0, debit_line])
|
||||
AccountMoveLine.append([0, 0, credit_line])
|
||||
|
||||
# Create account move lines for quants already out of stock
|
||||
if qty_out > 0:
|
||||
debit_line = dict(base_line,
|
||||
name=(self.name + ": " + str(qty_out) + _(' already out')),
|
||||
quantity=qty_out,
|
||||
quantity=0,
|
||||
account_id=already_out_account_id)
|
||||
credit_line = dict(base_line,
|
||||
name=(self.name + ": " + str(qty_out) + _(' already out')),
|
||||
quantity=qty_out,
|
||||
quantity=0,
|
||||
account_id=debit_account_id)
|
||||
diff = diff * qty_out / self.quantity
|
||||
if diff > 0:
|
||||
@@ -354,18 +356,18 @@ class AdjustmentLines(models.Model):
|
||||
# negative cost, reverse the entry
|
||||
debit_line['credit'] = -diff
|
||||
credit_line['debit'] = -diff
|
||||
AccountMoveLine.create(debit_line)
|
||||
AccountMoveLine.create(credit_line)
|
||||
AccountMoveLine.append([0, 0, debit_line])
|
||||
AccountMoveLine.append([0, 0, credit_line])
|
||||
|
||||
# TDE FIXME: oh dear
|
||||
if self.env.user.company_id.anglo_saxon_accounting:
|
||||
debit_line = dict(base_line,
|
||||
name=(self.name + ": " + str(qty_out) + _(' already out')),
|
||||
quantity=qty_out,
|
||||
quantity=0,
|
||||
account_id=credit_account_id)
|
||||
credit_line = dict(base_line,
|
||||
name=(self.name + ": " + str(qty_out) + _(' already out')),
|
||||
quantity=qty_out,
|
||||
quantity=0,
|
||||
account_id=already_out_account_id)
|
||||
|
||||
if diff > 0:
|
||||
@@ -375,7 +377,7 @@ class AdjustmentLines(models.Model):
|
||||
# negative cost, reverse the entry
|
||||
debit_line['credit'] = -diff
|
||||
credit_line['debit'] = -diff
|
||||
AccountMoveLine.create(debit_line)
|
||||
AccountMoveLine.create(credit_line)
|
||||
AccountMoveLine.append([0, 0, debit_line])
|
||||
AccountMoveLine.append([0, 0, credit_line])
|
||||
|
||||
return True
|
||||
return AccountMoveLine
|
||||
|
||||
@@ -1027,6 +1027,21 @@ var FieldPhone = FieldEmail.extend({
|
||||
this.$el.removeClass('o_text_overflow');
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove possibly present ­ characters when saving number
|
||||
*
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_setValue: function (value, options) {
|
||||
// NOT NEEDED AS OF SAAS-11.3
|
||||
if (value) {
|
||||
// remove possibly pasted ­ characters
|
||||
value = value.replace(/\u00AD/g, '');
|
||||
}
|
||||
return this._super(value, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Phone fields are clickable in readonly on small screens ~= on phones.
|
||||
* This can be overriden by call-capable modules to display a clickable
|
||||
|
||||
@@ -1292,12 +1292,27 @@ var FieldOne2Many = FieldX2Many.extend({
|
||||
// we don't want interference with the components upstream.
|
||||
ev.stopPropagation();
|
||||
|
||||
var self = this;
|
||||
var id = ev.data.id;
|
||||
// trigger an empty 'UPDATE' operation when the user clicks on 'Save' in
|
||||
// the dialog, to notify the main record that a subrecord of this
|
||||
// relational field has changed (those changes will be already stored on
|
||||
// that subrecord, thanks to the 'Save').
|
||||
var onSaved = this._setValue.bind(this, { operation: 'UPDATE', id: id }, {});
|
||||
var onSaved = function (record, hasChanged) {
|
||||
if (!hasChanged) {
|
||||
return;
|
||||
}
|
||||
if (_.some(self.value.data, {id: record.id})) {
|
||||
// the record already exists in the relation, so trigger an
|
||||
// empty 'UPDATE' operation when the user clicks on 'Save' in
|
||||
// the dialog, to notify the main record that a subrecord of
|
||||
// this relational field has changed (those changes will be
|
||||
// already stored on that subrecord, thanks to the 'Save').
|
||||
self._setValue({ operation: 'UPDATE', id: record.id });
|
||||
} else {
|
||||
// the record isn't in the relation yet, so add it ; this can
|
||||
// happen if the user clicks on 'Save & New' in the dialog (the
|
||||
// opened record will be updated, and other records will be
|
||||
// created)
|
||||
self._setValue({ operation: 'ADD', id: record.id });
|
||||
}
|
||||
};
|
||||
this._openFormDialog({
|
||||
id: id,
|
||||
on_saved: onSaved,
|
||||
|
||||
@@ -102,6 +102,18 @@ var AbstractController = Widget.extend(ControlPanelMixin, {
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
* Called each time the controller is attached into the DOM.
|
||||
*/
|
||||
on_attach_callback: function () {
|
||||
this.renderer.on_attach_callback();
|
||||
},
|
||||
/**
|
||||
* Called each time the controller is detached from the DOM.
|
||||
*/
|
||||
on_detach_callback: function () {
|
||||
this.renderer.on_detach_callback();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
|
||||
@@ -36,6 +36,14 @@ return Widget.extend({
|
||||
this.$el.addClass(this.arch.attrs.class);
|
||||
return $.when(this._render(), this._super());
|
||||
},
|
||||
/**
|
||||
* Called each time the renderer is attached into the DOM.
|
||||
*/
|
||||
on_attach_callback: function () {},
|
||||
/**
|
||||
* Called each time the renderer is detached from the DOM.
|
||||
*/
|
||||
on_detach_callback: function () {},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
|
||||
@@ -3167,6 +3167,9 @@ var BasicModel = AbstractModel.extend({
|
||||
* @param {Object} [options]
|
||||
* @param {string[]} [options.fieldNames] the fields to fetch for a record
|
||||
* @param {boolean} [options.onlyGroups=false]
|
||||
* @param {boolean} [options.keepEmptyGroups=false] if set, the groups not
|
||||
* present in the read_group anymore (empty groups) will stay in the
|
||||
* datapoint (used to mimic the kanban renderer behaviour for example)
|
||||
* @returns {Deferred}
|
||||
*/
|
||||
_load: function (dataPoint, options) {
|
||||
@@ -3319,9 +3322,29 @@ var BasicModel = AbstractModel.extend({
|
||||
*/
|
||||
_makeDefaultRecord: function (modelName, params) {
|
||||
var self = this;
|
||||
|
||||
var determineExtraFields = function() {
|
||||
// Fields that are present in the originating view, that need to be initialized
|
||||
// Hence preventing their value to crash when getting back to the originating view
|
||||
var parentRecord = self.localData[params.parentID];
|
||||
|
||||
var originView = parentRecord && parentRecord.fieldsInfo;
|
||||
if (!originView || !originView[parentRecord.viewType])
|
||||
return [];
|
||||
|
||||
var fieldsFromOrigin = _.filter(Object.keys(originView[parentRecord.viewType]),
|
||||
function(fieldname) {
|
||||
return params.fields[fieldname] !== undefined;
|
||||
});
|
||||
|
||||
return fieldsFromOrigin;
|
||||
}
|
||||
|
||||
var fieldNames = Object.keys(params.fieldsInfo[params.viewType]);
|
||||
var fields_key = _.without(fieldNames, '__last_update');
|
||||
|
||||
var extraFields = determineExtraFields();
|
||||
|
||||
return this._rpc({
|
||||
model: modelName,
|
||||
method: 'default_get',
|
||||
@@ -3339,7 +3362,7 @@ var BasicModel = AbstractModel.extend({
|
||||
viewType: params.viewType,
|
||||
});
|
||||
|
||||
return self.applyDefaultValues(record.id, result)
|
||||
return self.applyDefaultValues(record.id, result, {fieldNames: _.union(fieldNames, extraFields)})
|
||||
.then(function () {
|
||||
var def = $.Deferred();
|
||||
self._performOnChange(record, fields_key).always(function () {
|
||||
@@ -3603,6 +3626,8 @@ var BasicModel = AbstractModel.extend({
|
||||
} else if (_.contains(['one2many', 'many2many'], fieldType)) {
|
||||
var x2mCommands = commands[0][2][fieldName];
|
||||
defs.push(self._processX2ManyCommands(r, fieldName, x2mCommands));
|
||||
} else {
|
||||
r._changes[fieldName] = self._parseServerValue(field, r._changes[fieldName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3801,6 +3826,16 @@ var BasicModel = AbstractModel.extend({
|
||||
defs.push(self._load(newGroup, options));
|
||||
}
|
||||
});
|
||||
if (options && options.keepEmptyGroups) {
|
||||
// Find the groups that were available in a previous
|
||||
// readGroup but are not there anymore.
|
||||
// Note that these groups are put after existing groups so
|
||||
// the order is not conserved. A sort *might* be useful.
|
||||
var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data);
|
||||
_.each(emptyGroupsIDs, function (groupID) {
|
||||
list.data.push(groupID);
|
||||
});
|
||||
}
|
||||
return $.when.apply($, defs).then(function () {
|
||||
// generate the res_ids of the main list, being the concatenation
|
||||
// of the fetched res_ids in each group
|
||||
|
||||
@@ -253,7 +253,10 @@ return AbstractModel.extend({
|
||||
* @param {Moment} start
|
||||
*/
|
||||
setDate: function (start) {
|
||||
this.data.start_date = this.data.end_date = this.data.target_date = this.data.highlight_date = start;
|
||||
// keep highlight/target_date in localtime
|
||||
this.data.highlight_date = this.data.target_date = start.clone();
|
||||
// set dates in UTC with timezone applied manually
|
||||
this.data.start_date = this.data.end_date = start;
|
||||
this.data.start_date.utc().add(this.getSession().getTZOffset(this.data.start_date), 'minutes');
|
||||
|
||||
switch (this.data.scale) {
|
||||
|
||||
@@ -99,6 +99,7 @@ var FormController = BasicController.extend({
|
||||
* @todo convert to new style
|
||||
*/
|
||||
on_attach_callback: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.autofocus();
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,30 @@ return AbstractRenderer.extend({
|
||||
nv.utils.offWindowResize(this.to_remove);
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* The graph view uses the nv(d3) lib to render the graph. This lib requires
|
||||
* that the rendering is done directly into the DOM (so that it can correctly
|
||||
* compute positions). However, the views are always rendered in fragments,
|
||||
* and appended to the DOM once ready (to prevent them from flickering). We
|
||||
* here use the on_attach_callback hook, called when the widget is attached
|
||||
* to the DOM, to perform the rendering. This ensures that the rendering is
|
||||
* always done in the DOM.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
on_attach_callback: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.isInDOM = true;
|
||||
this._renderGraph();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
on_detach_callback: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.isInDOM = false;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -50,10 +74,9 @@ return AbstractRenderer.extend({
|
||||
* Render the chart.
|
||||
*
|
||||
* Note that This method is synchronous, but the actual rendering is done
|
||||
* asynchronously (in a setTimeout). The reason for that is that nvd3/d3
|
||||
* needs to be in the DOM to correctly render itself. So, we trick Odoo by
|
||||
* returning immediately, then wait a tiny interval before actually
|
||||
* displaying the data.
|
||||
* asynchronously. The reason for that is that nvd3/d3 needs to be in the
|
||||
* DOM to correctly render itself. So, we trick Odoo by returning
|
||||
* immediately, then we render the chart when the widget is in the DOM.
|
||||
*
|
||||
* @override
|
||||
* @private
|
||||
@@ -76,21 +99,15 @@ return AbstractRenderer.extend({
|
||||
description: _t("Try to add some records, or make sure that " +
|
||||
"there is no active filter in the search bar."),
|
||||
}));
|
||||
} else {
|
||||
var self = this;
|
||||
setTimeout(function () {
|
||||
self.$el.empty();
|
||||
var chart = self['_render' + _.str.capitalize(self.state.mode) + 'Chart']();
|
||||
if (chart && chart.tooltip.chartContainer) {
|
||||
self.to_remove = chart.update;
|
||||
nv.utils.onWindowResize(chart.update);
|
||||
chart.tooltip.chartContainer(self.el);
|
||||
}
|
||||
}, 0);
|
||||
} else if (this.isInDOM) {
|
||||
// only render the graph if the widget is already in the DOM (this
|
||||
// happens typically after an update), otherwise, it will be
|
||||
// rendered when the widget will be attached to the DOM (see
|
||||
// 'on_attach_callback')
|
||||
this._renderGraph();
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper function to set up data properly for the multiBarChart model in
|
||||
* nvd3.
|
||||
@@ -327,6 +344,21 @@ return AbstractRenderer.extend({
|
||||
chart(svg);
|
||||
return chart;
|
||||
},
|
||||
/**
|
||||
* Renders the graph according to its type. This function must be called
|
||||
* when the renderer is in the DOM (for nvd3 to render the graph correctly).
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_renderGraph: function () {
|
||||
this.$el.empty();
|
||||
var chart = this['_render' + _.str.capitalize(this.state.mode) + 'Chart']();
|
||||
if (chart && chart.tooltip.chartContainer) {
|
||||
this.to_remove = chart.update;
|
||||
nv.utils.onWindowResize(chart.update);
|
||||
chart.tooltip.chartContainer(this.el);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ odoo.define('web.KanbanController', function (require) {
|
||||
var BasicController = require('web.BasicController');
|
||||
var Context = require('web.Context');
|
||||
var core = require('web.core');
|
||||
var Domain = require('web.Domain');
|
||||
var view_dialogs = require('web.view_dialogs');
|
||||
|
||||
var _t = core._t;
|
||||
@@ -189,10 +190,57 @@ var KanbanController = BasicController.extend({
|
||||
resIDs: record.res_ids,
|
||||
},
|
||||
on_closed: function () {
|
||||
var recordModel = self.model.localData[record.id];
|
||||
var group = self.model.localData[recordModel.parentID];
|
||||
var parent = self.model.localData[group.parentID];
|
||||
|
||||
self.model.reload(record.id).then(function (db_id) {
|
||||
var data = self.model.get(db_id);
|
||||
var kanban_record = event.target;
|
||||
kanban_record.update(data);
|
||||
|
||||
// Check if we still need to display the record. Some fields of the domain are
|
||||
// not guaranteed to be in data. This is for example the case if the action
|
||||
// contains a domain on a field which is not in the Kanban view. Therefore,
|
||||
// we need to handle multiple cases based on 3 variables:
|
||||
// domInData: all domain fields are in the data
|
||||
// activeInDomain: 'active' is already in the domain
|
||||
// activeInData: 'active' is available in the data
|
||||
|
||||
var domain = (parent ? parent.domain : group.domain) || [];
|
||||
var domInData = _.every(domain, function (d) {
|
||||
return d[0] in data.data;
|
||||
});
|
||||
var activeInDomain = _.pluck(domain, 0).indexOf('active') !== -1;
|
||||
var activeInData = 'active' in data.data;
|
||||
|
||||
// Case # | domInData | activeInDomain | activeInData
|
||||
// 1 | true | true | true => no domain change
|
||||
// 2 | true | true | false => not possible
|
||||
// 3 | true | false | true => add active in domain
|
||||
// 4 | true | false | false => no domain change
|
||||
// 5 | false | true | true => no evaluation
|
||||
// 6 | false | true | false => no evaluation
|
||||
// 7 | false | false | true => replace domain
|
||||
// 8 | false | false | false => no evaluation
|
||||
|
||||
// There are 3 cases which cannot be evaluated since we don't have all the
|
||||
// necessary information. The complete solution would be to perform a RPC in
|
||||
// these cases, but this is out of scope. A simpler one is to do a try / catch.
|
||||
|
||||
if (domInData && !activeInDomain && activeInData) {
|
||||
domain = domain.concat([['active', '=', true]]);
|
||||
} else if (!domInData && !activeInDomain && activeInData) {
|
||||
domain = [['active', '=', true]];
|
||||
}
|
||||
try {
|
||||
var visible = new Domain(domain).compute(data.evalContext);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
if (!visible) {
|
||||
kanban_record.destroy();
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -419,7 +419,10 @@ var KanbanModel = BasicModel.extend({
|
||||
while (element) {
|
||||
if (element.progressBar) {
|
||||
return def.then(function (data) {
|
||||
return self._load(element, {onlyGroups: true}).then(function () {
|
||||
return self._load(element, {
|
||||
keepEmptyGroups: true,
|
||||
onlyGroups: true,
|
||||
}).then(function () {
|
||||
return data;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
.o_datepicker_input {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.o_datepicker_button {
|
||||
.o-position-absolute(2px, 4px);
|
||||
cursor: pointer;
|
||||
pointer-events: none; // let click events go through the underlying input
|
||||
&:after {
|
||||
.o-caret-down;
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
vertical-align: baseline;
|
||||
> .o_priority_star {
|
||||
display: inline-block;
|
||||
font-size: 1.35em;
|
||||
|
||||
@@ -248,6 +248,10 @@
|
||||
border-left-color: @gray-lighter;
|
||||
}
|
||||
}
|
||||
|
||||
.caret {
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.o-status-more {
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
margin-left: 3%;
|
||||
color: @headings-color;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
.o-transform-origin(right, center);
|
||||
|
||||
&.o_kanban_grow {
|
||||
|
||||
@@ -223,6 +223,7 @@
|
||||
}
|
||||
|
||||
.o_favorite {
|
||||
top: 3px;
|
||||
left: 0;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,14 @@
|
||||
.user-select(none); // Prevent unwanted selection while sorting
|
||||
|
||||
&::after {
|
||||
margin-left: 6px;
|
||||
position: absolute;
|
||||
font-family: FontAwesome;
|
||||
content: "\f0d7";
|
||||
opacity: 0;
|
||||
}
|
||||
&:not(:empty)::after {
|
||||
margin-left: 6px;
|
||||
position: absolute;
|
||||
}
|
||||
&.o-sort-up {
|
||||
cursor: n-resize;
|
||||
&::after {
|
||||
|
||||
@@ -3080,7 +3080,7 @@ QUnit.module('basic_fields', {
|
||||
QUnit.module('PhoneWidget');
|
||||
|
||||
QUnit.test('phone field in form view on extra small screens', function (assert) {
|
||||
assert.expect(7);
|
||||
assert.expect(8);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
@@ -3127,6 +3127,15 @@ QUnit.module('basic_fields', {
|
||||
assert.strictEqual($phoneLink.attr('href'), 'tel:new',
|
||||
"should still have proper tel prefix");
|
||||
|
||||
// NOT NEEDED AS OF SAAS-11.3
|
||||
// save phone with ­ and verify it is removed
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
form.$('input[type="text"].o_field_widget').val('h\u00ADi').trigger('input');
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
$phoneLink = form.$('a.o_form_uri.o_field_widget');
|
||||
assert.strictEqual($phoneLink.attr('href'), 'tel:hi',
|
||||
"U+00AD should have been removed");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
|
||||
@@ -4246,7 +4246,6 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('one2many list (non editable): edition', function (assert) {
|
||||
assert.expect(12);
|
||||
|
||||
@@ -5115,6 +5114,32 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('one2many and default_get (with date)', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
this.data.partner.fields.p.default = [
|
||||
[0, false, {date: '2017-10-08'}],
|
||||
];
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch:'<form string="Partners">' +
|
||||
'<field name="p">' +
|
||||
'<tree>' +
|
||||
'<field name="date"/>' +
|
||||
'</tree>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_data_cell').text(), '10/08/2017',
|
||||
"should correctly display the date");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('one2many and onchange (with integer)', function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
@@ -8780,6 +8805,53 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('add a line, edit it and "Save & New"', function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<field name="p">' +
|
||||
'<tree><field name="display_name"/></tree>' +
|
||||
'<form><field name="display_name"/></form>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
});
|
||||
|
||||
assert.strictEqual(form.$('.o_data_row').length, 0,
|
||||
"there should be no record in the relation");
|
||||
|
||||
// add a new record
|
||||
form.$('.o_field_x2many_list_row_add a').click();
|
||||
$('.modal .o_field_widget').val('new record').trigger('input');
|
||||
$('.modal .modal-footer .btn-primary:first').click(); // Save & Close
|
||||
|
||||
assert.strictEqual(form.$('.o_data_row .o_data_cell').text(), 'new record',
|
||||
"should display the new record");
|
||||
|
||||
// reopen freshly added record and edit it
|
||||
form.$('.o_data_row .o_data_cell').click();
|
||||
$('.modal .o_field_widget').val('new record edited').trigger('input');
|
||||
|
||||
// save it, and choose to directly create another record
|
||||
$('.modal .modal-footer .btn-primary:nth(1)').click(); // Save & New
|
||||
|
||||
assert.strictEqual($('.modal').length, 1,
|
||||
"the model should still be open");
|
||||
assert.strictEqual($('.modal .o_field_widget').text(), '',
|
||||
"should have cleared the input");
|
||||
|
||||
$('.modal .o_field_widget').val('another new record').trigger('input');
|
||||
$('.modal .modal-footer .btn-primary:first').click(); // Save & Close
|
||||
|
||||
assert.strictEqual(form.$('.o_data_row .o_data_cell').text(),
|
||||
'new record editedanother new record', "should display the two records");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldMany2Many');
|
||||
|
||||
QUnit.test('many2many kanban: edition', function (assert) {
|
||||
@@ -11304,6 +11376,78 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('one2many with extra field from server not in form', function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<field name="p" >' +
|
||||
'<tree>' +
|
||||
'<field name="datetime"/>' +
|
||||
'<field name="display_name"/>' +
|
||||
'</tree>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
res_id: 1,
|
||||
archs: {
|
||||
'partner,false,form': '<form>' +
|
||||
'<field name="display_name"/>' +
|
||||
'</form>'},
|
||||
mockRPC: function(route, args) {
|
||||
if (route === '/web/dataset/call_kw/partner/write') {
|
||||
args.args[1].p[0][2].datetime = '2018-04-05 12:00:00';
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
form.$buttons.find('.o_form_button_edit').click();
|
||||
|
||||
var x2mList = form.$('.o_field_x2many_list[name=p]');
|
||||
|
||||
// Add a record in the list
|
||||
x2mList.find('.o_field_x2many_list_row_add a').click();
|
||||
|
||||
var modal = $('.modal-dialog.modal-lg');
|
||||
|
||||
var nameInput = modal.find('input.o_input[name=display_name]');
|
||||
nameInput.val('michelangelo').trigger('input');
|
||||
|
||||
// Save the record in the modal (though it is still virtual)
|
||||
modal.find('.btn-primary').first().click();
|
||||
|
||||
assert.equal(x2mList.find('.o_data_row').length, 1,
|
||||
'There should be 1 records in the x2m list');
|
||||
|
||||
var newlyAdded = x2mList.find('.o_data_row').eq(0);
|
||||
|
||||
assert.equal(newlyAdded.find('.o_data_cell').first().text(), '',
|
||||
'The create_date field should be empty');
|
||||
assert.equal(newlyAdded.find('.o_data_cell').eq(1).text(), 'michelangelo',
|
||||
'The display name field should have the right value');
|
||||
|
||||
// Save the whole thing
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
x2mList = form.$('.o_field_x2many_list[name=p]');
|
||||
|
||||
// Redo asserts in RO mode after saving
|
||||
assert.equal(x2mList.find('.o_data_row').length, 1,
|
||||
'There should be 1 records in the x2m list');
|
||||
|
||||
newlyAdded = x2mList.find('.o_data_row').eq(0);
|
||||
|
||||
assert.equal(newlyAdded.find('.o_data_cell').first().text(), '04/05/2018 12:00:00',
|
||||
'The create_date field should have the right value');
|
||||
assert.equal(newlyAdded.find('.o_data_cell').eq(1).text(), 'michelangelo',
|
||||
'The display name field should have the right value');
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('one2many invisible depends on parent field', function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
|
||||
@@ -1824,6 +1824,41 @@ QUnit.module('Views', {
|
||||
assert.ok(!$groupBy.is(':visible'), 'groupby menu should not be visible');
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('timezone does not affect current day', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var calendar = createView({
|
||||
View: CalendarView,
|
||||
model: 'event',
|
||||
data: this.data,
|
||||
arch:
|
||||
'<calendar date_start="start_date">'+
|
||||
'<field name="name"/>'+
|
||||
'</calendar>',
|
||||
archs: archs,
|
||||
viewOptions: {
|
||||
initialDate: initialDate,
|
||||
},
|
||||
session: {
|
||||
getTZOffset: function () {
|
||||
return -2400; // 40 hours timezone
|
||||
},
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
var $sidebar = calendar.$('.o_calendar_sidebar');
|
||||
|
||||
assert.strictEqual($sidebar.find('.ui-datepicker-current-day').text(), "12", "should highlight the target day");
|
||||
|
||||
// go to previous day
|
||||
$sidebar.find('.ui-datepicker-current-day').prev().click();
|
||||
|
||||
assert.strictEqual($sidebar.find('.ui-datepicker-current-day').text(), "11", "should highlight the selected day");
|
||||
|
||||
calendar.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -2511,6 +2511,73 @@ QUnit.module('Views', {
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('button executes action and check domain', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
var data = this.data;
|
||||
data.partner.fields.active = {string: "Active", type: "boolean", default: true};
|
||||
for (var k in this.data.partner.records) {
|
||||
data.partner.records[k].active = true;
|
||||
}
|
||||
|
||||
var kanban = createView({
|
||||
View: KanbanView,
|
||||
model: "partner",
|
||||
data: data,
|
||||
arch:
|
||||
'<kanban>' +
|
||||
'<templates><div t-name="kanban-box">' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="active"/>' +
|
||||
'<button type="object" name="a1" />' +
|
||||
'<button type="object" name="toggle_active" />' +
|
||||
'</div></templates>' +
|
||||
'</kanban>',
|
||||
});
|
||||
|
||||
testUtils.intercept(kanban, 'execute_action', function (event) {
|
||||
data.partner.records[0].active = false;
|
||||
event.data.on_closed();
|
||||
});
|
||||
|
||||
assert.strictEqual(kanban.$('.o_kanban_record:contains(yop)').length, 1, "should display 'yop' record");
|
||||
kanban.$('.o_kanban_record:contains(yop) button[data-name="toggle_active"]').click();
|
||||
assert.strictEqual(kanban.$('.o_kanban_record:contains(yop)').length, 0, "should remove 'yop' record from the view");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('button executes action with domain field not in view', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var kanban = createView({
|
||||
View: KanbanView,
|
||||
model: "partner",
|
||||
data: this.data,
|
||||
domain: [['bar', '=', true]],
|
||||
arch:
|
||||
'<kanban>' +
|
||||
'<templates><div t-name="kanban-box">' +
|
||||
'<field name="foo"/>' +
|
||||
'<button type="object" name="a1" />' +
|
||||
'<button type="object" name="toggle_action" />' +
|
||||
'</div></templates>' +
|
||||
'</kanban>',
|
||||
});
|
||||
|
||||
testUtils.intercept(kanban, 'execute_action', function (event) {
|
||||
event.data.on_closed();
|
||||
});
|
||||
|
||||
try {
|
||||
kanban.$('.o_kanban_record:contains(yop) button[data-name="toggle_action"]').click();
|
||||
assert.strictEqual(true, true, 'Everything went fine');
|
||||
} catch (e) {
|
||||
assert.strictEqual(true, false, 'Error triggered at action execution');
|
||||
}
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('rendering date and datetime', function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
@@ -3150,6 +3217,51 @@ QUnit.module('Views', {
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('drag & drop records grouped by m2o with progressbar', function (assert) {
|
||||
assert.expect(4);
|
||||
|
||||
this.data.partner.records[0].product_id = false;
|
||||
|
||||
var kanban = createView({
|
||||
View: KanbanView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch:
|
||||
'<kanban>' +
|
||||
'<progressbar field="foo" colors=\'{"yop": "success", "gnap": "warning", "blip": "danger"}\'/>' +
|
||||
'<templates><t t-name="kanban-box">' +
|
||||
'<div>' +
|
||||
'<field name="int_field"/>' +
|
||||
'</div>' +
|
||||
'</t></templates>' +
|
||||
'</kanban>',
|
||||
groupBy: ['product_id'],
|
||||
mockRPC: function (route, args) {
|
||||
if (route === '/web/dataset/resequence') {
|
||||
return $.when(true);
|
||||
}
|
||||
return this._super(route, args);
|
||||
},
|
||||
});
|
||||
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "1",
|
||||
"counter should contain the correct value");
|
||||
|
||||
testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(0) .o_kanban_record:eq(0)'), kanban.$('.o_kanban_group:eq(1)'));
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "0",
|
||||
"counter should contain the correct value");
|
||||
|
||||
testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(1) .o_kanban_record:eq(2)'), kanban.$('.o_kanban_group:eq(0)'));
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "1",
|
||||
"counter should contain the correct value");
|
||||
|
||||
testUtils.dragAndDrop(kanban.$('.o_kanban_group:eq(0) .o_kanban_record:eq(0)'), kanban.$('.o_kanban_group:eq(1)'));
|
||||
assert.strictEqual(kanban.$('.o_kanban_group:eq(0) .o_kanban_counter_side').text(), "0",
|
||||
"counter should contain the correct value");
|
||||
|
||||
kanban.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('progress bar subgroup count recompute', function(assert) {
|
||||
assert.expect(2);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
from odoo.osv import expression
|
||||
|
||||
|
||||
class IrHttp(models.AbstractModel):
|
||||
@@ -19,3 +20,8 @@ class IrHttp(models.AbstractModel):
|
||||
context['translatable'] = True
|
||||
request.context = context
|
||||
return super(IrHttp, cls)._dispatch()
|
||||
|
||||
@classmethod
|
||||
def _get_translation_frontend_modules_domain(cls):
|
||||
domain = super(IrHttp, cls)._get_translation_frontend_modules_domain()
|
||||
return expression.OR([domain, [('name', '=', 'web_editor')]])
|
||||
|
||||
@@ -1800,12 +1800,17 @@ $.summernote.pluginEvents.indent = function (event, editor, layoutInfo, outdent)
|
||||
var $dom = $(ancestor);
|
||||
|
||||
if (!dom.isList(ancestor)) {
|
||||
// to indent a selection, we indent the child nodes of the common
|
||||
// ancestor that contains this selection
|
||||
$dom = $(dom.node(ancestor)).children();
|
||||
}
|
||||
if (!$dom.length) {
|
||||
$dom = $(dom.ancestor(r.sc, dom.isList) || dom.ancestor(r.sc, dom.isCell));
|
||||
if (!$dom.not('br').length) {
|
||||
// if selection is inside a list, we indent its list items
|
||||
$dom = $(dom.ancestor(r.sc, dom.isList));
|
||||
if (!$dom.length) {
|
||||
$dom = $(r.sc).closest(options.styleTags.join(','));
|
||||
// if the selection is contained in a single HTML node, we indent
|
||||
// the first ancestor 'content block' (P, H1, PRE, ...) or TD
|
||||
$dom = $(r.sc).closest(options.styleTags.join(',')+',td');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -295,17 +295,6 @@ class Website(Home):
|
||||
modules.button_immediate_upgrade()
|
||||
return request.redirect(redirect)
|
||||
|
||||
@http.route('/website/translations', type='json', auth="public", website=True)
|
||||
def get_website_translations(self, lang, mods=None):
|
||||
Modules = request.env['ir.module.module'].sudo()
|
||||
modules = Modules.search([
|
||||
'|', ('name', 'ilike', 'website'), ('name', '=', 'web_editor'),
|
||||
('state', '=', 'installed')
|
||||
]).mapped('name')
|
||||
if mods:
|
||||
modules += mods
|
||||
return WebClient().translations(mods=modules, lang=lang)
|
||||
|
||||
@http.route(['/website/publish'], type='json', auth="public", website=True)
|
||||
def publish(self, id, object):
|
||||
Model = request.env[object]
|
||||
|
||||
@@ -17,7 +17,7 @@ from odoo.http import request
|
||||
from odoo.tools import config
|
||||
from odoo.exceptions import QWebException
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
from odoo.osv.expression import FALSE_DOMAIN
|
||||
from odoo.osv.expression import FALSE_DOMAIN, OR
|
||||
|
||||
from odoo.addons.http_routing.models.ir_http import ModelConverter, _guess_mimetype
|
||||
from odoo.addons.portal.controllers.portal import _build_url_w_params
|
||||
@@ -104,6 +104,11 @@ class Http(models.AbstractModel):
|
||||
return request.website.default_lang_id
|
||||
return super(Http, cls)._get_default_lang()
|
||||
|
||||
@classmethod
|
||||
def _get_translation_frontend_modules_domain(cls):
|
||||
domain = super(Http, cls)._get_translation_frontend_modules_domain()
|
||||
return OR([domain, [('name', 'ilike', 'website')]])
|
||||
|
||||
@classmethod
|
||||
def _serve_page(cls):
|
||||
req_page = request.httprequest.path
|
||||
|
||||
@@ -92,6 +92,7 @@ tour.register('event_buy_tickets', {
|
||||
{
|
||||
content: "Last step",
|
||||
trigger: '.oe_website_sale:contains("Thank you for your order")',
|
||||
timeout: 30000,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
@@ -20,7 +20,11 @@ odoo.define('website_form.animation', function (require) {
|
||||
return $.when(this._super.apply(this, arguments), def);
|
||||
},
|
||||
|
||||
start: function () {
|
||||
start: function (editable_mode) {
|
||||
if (editable_mode) {
|
||||
this.stop();
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
this.templates_loaded = ajax.loadXML('/website_form/static/src/xml/website_form.xml', qweb);
|
||||
this.$target.find('.o_website_form_send').on('click',function (e) {self.send(e);});
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_saleorder_validity_date" inherit_id="sale.report_saleorder_document">
|
||||
<xpath expr="//div[hasclass('page')]/div[@id='informations']" position="inside">
|
||||
<div t-if="doc.validity_date and doc.state in ['draft', 'sent']" class="col-xs-3">
|
||||
<strong>Expiration Date:</strong>
|
||||
<p t-field="doc.validity_date"/>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('page')]/p[@id='fiscal_position_remark']" position="after">
|
||||
<div t-if="doc.options and doc.state in ['draft', 'sent']" style="page-break-before:always;">
|
||||
<h2>
|
||||
|
||||
@@ -31,7 +31,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
], string="Shipping Management")
|
||||
|
||||
group_website_multiimage = fields.Boolean(string='Multi-Images', implied_group='website_sale.group_website_multi_image', group='base.group_portal,base.group_user,base.group_public')
|
||||
group_delivery_invoice_address = fields.Boolean(string="Shipping Address", implied_group='sale.group_delivery_invoice_address')
|
||||
group_delivery_invoice_address = fields.Boolean(string="Shipping Address", implied_group='sale.group_delivery_invoice_address', group='base.group_portal,base.group_user,base.group_public')
|
||||
|
||||
module_website_sale_options = fields.Boolean("Optional Products")
|
||||
module_website_sale_digital = fields.Boolean("Digital Content")
|
||||
|
||||
@@ -82,6 +82,7 @@ tour.register('shop_buy_product', {
|
||||
{
|
||||
content: "finish",
|
||||
trigger: '.oe_website_sale:contains("Thank you for your order")',
|
||||
timeout: 30000,
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
@@ -443,7 +443,7 @@
|
||||
<li t-if="variant_img" data-target="#o-carousel-product" data-slide-to="0" class="active">
|
||||
<img class="img img-responsive js_variant_img_small" t-attf-src="/website/image/product.product/{{product.product_variant_id.id}}/image/90x90" t-att-alt="product.name"/>
|
||||
</li>
|
||||
<li data-target="#o-carousel-product" t-att-data-slide-to="1 if variant_img else 0" t-att-class="'' if variant_img else 'active'">
|
||||
<li data-target="#o-carousel-product" t-att-data-slide-to="1 if variant_img else '0'" t-att-class="'' if variant_img else 'active'">
|
||||
<img class="img img-responsive" t-attf-src="/website/image/product.template/{{product.id}}/image/90x90" t-att-alt="product.name"/>
|
||||
</li>
|
||||
<t t-if="len(image_ids)" t-foreach="image_ids" t-as="pimg">
|
||||
|
||||
@@ -39,3 +39,8 @@ class WebsiteSaleWishlist(WebsiteSale):
|
||||
return request.redirect("/shop")
|
||||
|
||||
return request.render("website_sale_wishlist.product_wishlist", dict(wishes=values))
|
||||
|
||||
@http.route(['/shop/wishlist/remove/<model("product.wishlist"):wish>'], type='json', auth="public", website=True)
|
||||
def rm_from_wishlist(self, wish, **kw):
|
||||
wish.active = False
|
||||
return True
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user