[MERGE] forward port of branch 8.0 up to ea54d4a
This commit is contained in:
@@ -6,5 +6,6 @@ Contributing to Odoo
|
||||
TL;DR
|
||||
|
||||
* Use this [template](https://github.com/odoo/odoo/wiki/Contributing#reporting-issues) when reporting issues, and please search for duplicates first!
|
||||
* The issues not linked to pull requests will be handled with a low priority.
|
||||
* Pull requests must be made against the [correct version](https://github.com/odoo/odoo/wiki/Contributing#against-which-version-should-i-submit-a-patch)
|
||||
* There are restrictions on the kind of [changes allowed in stable series](https://github.com/odoo/odoo/wiki/Contributing#what-does-stable-mean)
|
||||
|
||||
@@ -5,43 +5,23 @@ Odoo
|
||||
|
||||
Odoo is a suite of web based open source business apps.
|
||||
|
||||
The main Odoo Apps include an <a href="https://www.odoo.com/page/crm">Open Source CRM</a>, <a href="https://www.odoo.com/page/website-builder">Website Builder</a>, <a href="https://www.odoo.com/page/e-commerce">eCommerce</a>, <a href="https://www.odoo.com/page/project-management">Project Management</a>, <a href="https://www.odoo.com/page/accounting">Billing & Accounting</a>, <a href="https://www.odoo.com/page/point-of-sale">Point of Sale</a>, <a href="https://www.odoo.com/page/employees">Human Resources</a>, Marketing, Manufacturing, Purchase Management, ...
|
||||
The main Odoo Apps include an <a href="https://www.odoo.com/page/crm">Open Source CRM</a>, <a href="https://www.odoo.com/page/website-builder">Website Builder</a>, <a href="https://www.odoo.com/page/e-commerce">eCommerce</a>, <a href="https://www.odoo.com/page/project-management">Project Management</a>, <a href="https://www.odoo.com/page/accounting">Billing & Accounting</a>, <a href="https://www.odoo.com/page/point-of-sale">Point of Sale</a>, <a href="https://www.odoo.com/page/employees">Human Resources</a>, Marketing, Manufacturing, Purchase Management, ...
|
||||
|
||||
Odoo Apps can be used as stand-alone applications, but they also integrate seamlessly so you get
|
||||
a full-featured <a href="https://www.odoo.com">Open Source ERP</a> when you install several Apps.
|
||||
|
||||
|
||||
Getting started with Odoo development
|
||||
--------------------------------------
|
||||
Getting started with Odoo
|
||||
-------------------------
|
||||
|
||||
If you are a developer type the following command at your terminal:
|
||||
For a standard installation please follow the <a href="https://www.odoo.com/documentation/8.0/setup/install.html">Setup instructions</a>
|
||||
from the documentation.
|
||||
|
||||
If you are a developer you may type the following command at your terminal:
|
||||
|
||||
wget -O- https://raw.githubusercontent.com/odoo/odoo/master/odoo.py | python
|
||||
|
||||
Then follow <a href="https://doc.odoo.com/trunk/server/howto/howto_website/">the developer tutorial</a>
|
||||
|
||||
|
||||
|
||||
Packages, tarballs and installers
|
||||
---------------------------------
|
||||
|
||||
* Debian packages
|
||||
|
||||
Add this apt repository to your /etc/apt/sources.list file
|
||||
|
||||
deb http://nightly.odoo.com/master/nightly/deb/ ./
|
||||
|
||||
Then type:
|
||||
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install odoo
|
||||
|
||||
If you plan to use Odoo with a local database, please make sure to install PostgreSQL *before* installing the Odoo Debian package.
|
||||
|
||||
* <a href="http://nightly.odoo.com/master/nightly/src/">Source tarballs</a>
|
||||
|
||||
* <a href="http://nightly.odoo.com/master/nightly/exe/">Windows installer</a>
|
||||
|
||||
* <a href="http://nightly.odoo.com/master/nightly/rpm/">RPM package</a>
|
||||
Then follow <a href="https://www.odoo.com/documentation/8.0/tutorials.html">the developer tutorials</a>
|
||||
|
||||
|
||||
For Odoo employees
|
||||
|
||||
@@ -1261,7 +1261,7 @@ class account_invoice_line(models.Model):
|
||||
uos_id = fields.Many2one('product.uom', string='Unit of Measure',
|
||||
ondelete='set null', index=True)
|
||||
product_id = fields.Many2one('product.product', string='Product',
|
||||
ondelete='set null', index=True)
|
||||
ondelete='restrict', index=True)
|
||||
account_id = fields.Many2one('account.account', string='Account',
|
||||
required=True, domain=[('type', 'not in', ['view', 'closed'])],
|
||||
default=_default_account,
|
||||
|
||||
@@ -1197,7 +1197,7 @@ class account_move_line(osv.osv):
|
||||
if journal.centralisation:
|
||||
self._check_moves(cr, uid, context=ctx)
|
||||
result = super(account_move_line, self).write(cr, uid, ids, vals, context)
|
||||
if check:
|
||||
if check and not context.get('novalidate'):
|
||||
done = []
|
||||
for line in self.browse(cr, uid, ids):
|
||||
if line.move_id.id not in done:
|
||||
@@ -1339,24 +1339,23 @@ class account_move_line(osv.osv):
|
||||
account_id = 'account_paid_id'
|
||||
base_sign = 'ref_base_sign'
|
||||
tax_sign = 'ref_tax_sign'
|
||||
tmp_cnt = 0
|
||||
base_adjusted = False
|
||||
for tax in tax_obj.compute_all(cr, uid, [tax_id], total, 1.00, force_excluded=False).get('taxes'):
|
||||
#create the base movement
|
||||
if tmp_cnt == 0:
|
||||
if tax[base_code]:
|
||||
tmp_cnt += 1
|
||||
if tax_id.price_include:
|
||||
total = tax['price_unit']
|
||||
newvals = {
|
||||
'tax_code_id': tax[base_code],
|
||||
'tax_amount': tax[base_sign] * abs(total),
|
||||
}
|
||||
if tax_id.price_include:
|
||||
if tax['price_unit'] < 0:
|
||||
newvals['credit'] = abs(tax['price_unit'])
|
||||
else:
|
||||
newvals['debit'] = tax['price_unit']
|
||||
self.write(cr, uid, [result], newvals, context=context)
|
||||
if base_adjusted == False:
|
||||
base_adjusted = True
|
||||
if tax_id.price_include:
|
||||
total = tax['price_unit']
|
||||
newvals = {
|
||||
'tax_code_id': tax[base_code],
|
||||
'tax_amount': tax[base_sign] * abs(total),
|
||||
}
|
||||
if tax_id.price_include:
|
||||
if tax['price_unit'] < 0:
|
||||
newvals['credit'] = abs(tax['price_unit'])
|
||||
else:
|
||||
newvals['debit'] = tax['price_unit']
|
||||
self.write(cr, uid, [result], newvals, context=context)
|
||||
else:
|
||||
data = {
|
||||
'move_id': vals['move_id'],
|
||||
@@ -1372,8 +1371,7 @@ class account_move_line(osv.osv):
|
||||
'credit': 0.0,
|
||||
'debit': 0.0,
|
||||
}
|
||||
if data['tax_code_id']:
|
||||
self.create(cr, uid, data, context)
|
||||
self.create(cr, uid, data, context)
|
||||
#create the Tax movement
|
||||
data = {
|
||||
'move_id': vals['move_id'],
|
||||
@@ -1389,8 +1387,7 @@ class account_move_line(osv.osv):
|
||||
'credit': tax['amount']<0 and -tax['amount'] or 0.0,
|
||||
'debit': tax['amount']>0 and tax['amount'] or 0.0,
|
||||
}
|
||||
if data['tax_code_id']:
|
||||
self.create(cr, uid, data, context)
|
||||
self.create(cr, uid, data, context)
|
||||
del vals['account_tax_id']
|
||||
|
||||
if check and not context.get('novalidate') and (context.get('recompute', True) or journal.entry_posted):
|
||||
|
||||
@@ -625,7 +625,7 @@
|
||||
<label for="balance_end" />
|
||||
<button name="button_dummy" states="draft" string="(update)" type="object" class="oe_edit_only oe_link"/>
|
||||
</div>
|
||||
<field name="balance_end" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency_id'}"/>
|
||||
<field name="balance_end" nolabel="1" class="oe_subtotal_footer_separator" widget='monetary' options="{'currency_field': 'currency'}"/>
|
||||
</group>
|
||||
<div class="oe_clear"/>
|
||||
</sheet>
|
||||
@@ -1097,7 +1097,9 @@
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"
|
||||
on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="journal_id"/>
|
||||
@@ -1170,7 +1172,9 @@
|
||||
<field name="journal_id" readonly="False"/>
|
||||
<field name="period_id" readonly="False"/>
|
||||
<field name="account_id" domain="[('type','<>','view'),('type','<>','consolidation'),('company_id', '=', company_id)]"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"
|
||||
on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
<newline/>
|
||||
<field name="debit"/>
|
||||
<field name="credit"/>
|
||||
@@ -1214,7 +1218,9 @@
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="statement_id" invisible="1"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(move_id, partner_id, account_id, debit, credit, date, journal_id)"/>
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"
|
||||
on_change="onchange_partner_id(move_id, partner_id, account_id, debit, credit, date, journal_id)"/>
|
||||
<field name="account_id" options='{"no_open":True}' domain="[('journal_id','=',journal_id), ('company_id', '=', company_id)]" on_change="onchange_account_id(account_id, partner_id, context)"/>
|
||||
<field name="account_tax_id" options='{"no_open":True}' invisible="context.get('journal_type', False) not in ['sale','sale_refund','purchase','purchase_refund','general']"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('type','not in',['view','template'])]" invisible="not context.get('analytic_journal_id',False)"/>
|
||||
@@ -1396,7 +1402,9 @@
|
||||
<group col="6" colspan="4">
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False, partner_id, account_id, debit, credit, date, journal_id, context)"/>
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"
|
||||
on_change="onchange_partner_id(False, partner_id, account_id, debit, credit, date, journal_id, context)"/>
|
||||
|
||||
<field name="journal_id"/>
|
||||
<field name="period_id"/>
|
||||
@@ -1460,7 +1468,9 @@
|
||||
<tree colors="blue:state == 'draft';black:state == 'posted'" editable="top" string="Journal Items">
|
||||
<field name="invoice"/>
|
||||
<field name="name"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False, partner_id, account_id, debit, credit, parent.date, parent.journal_id, context)"/>
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"
|
||||
on_change="onchange_partner_id(False, partner_id, account_id, debit, credit, parent.date, parent.journal_id, context)"/>
|
||||
<field name="account_id" domain="[('journal_id','=',parent.journal_id),('company_id', '=', parent.company_id)]"/>
|
||||
<field name="date_maturity"/>
|
||||
<field name="debit" sum="Total Debit"/>
|
||||
|
||||
@@ -155,10 +155,10 @@ class aged_trial_report(report_sxw.rml_parse, common_report_header):
|
||||
dates_query += ' BETWEEN %s AND %s)'
|
||||
args_list += (form[str(i)]['start'], form[str(i)]['stop'])
|
||||
elif form[str(i)]['start']:
|
||||
dates_query += ' > %s)'
|
||||
dates_query += ' >= %s)'
|
||||
args_list += (form[str(i)]['start'],)
|
||||
else:
|
||||
dates_query += ' < %s)'
|
||||
dates_query += ' <= %s)'
|
||||
args_list += (form[str(i)]['stop'],)
|
||||
args_list += (self.date_from,)
|
||||
self.cr.execute('''SELECT l.partner_id, SUM(l.debit-l.credit), l.reconcile_partial_id
|
||||
@@ -181,11 +181,21 @@ class aged_trial_report(report_sxw.rml_parse, common_report_header):
|
||||
# in case of partial reconciliation, we want to keep the left amount in the oldest period
|
||||
self.cr.execute('''SELECT MIN(COALESCE(date_maturity,date)) FROM account_move_line WHERE reconcile_partial_id = %s''', (partner_info[2],))
|
||||
date = self.cr.fetchall()
|
||||
if date and args_list[-3] <= date[0][0] <= args_list[-2]:
|
||||
partial = False
|
||||
if 'BETWEEN' in dates_query:
|
||||
partial = date and args_list[-3] <= date[0][0] <= args_list[-2]
|
||||
elif '>=' in dates_query:
|
||||
partial = date and date[0][0] >= form[str(i)]['start']
|
||||
else:
|
||||
partial = date and date[0][0] <= form[str(i)]['stop']
|
||||
if partial:
|
||||
# partial reconcilation
|
||||
limit_date = 'COALESCE(l.date_maturity,l.date) %s %%s' % '<=' if self.direction_selection == 'past' else '>='
|
||||
self.cr.execute('''SELECT SUM(l.debit-l.credit)
|
||||
FROM account_move_line AS l
|
||||
WHERE l.reconcile_partial_id = %s''', (partner_info[2],))
|
||||
FROM account_move_line AS l, account_move AS am
|
||||
WHERE l.move_id = am.id AND am.state in %s
|
||||
AND l.reconcile_partial_id = %s
|
||||
AND ''' + limit_date, (tuple(move_state), partner_info[2], self.date_from))
|
||||
unreconciled_amount = self.cr.fetchall()
|
||||
partners_amount[partner_info[0]] += unreconciled_amount[0][0]
|
||||
else:
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
groups="group_account_manager"
|
||||
context="{'search_default_partner_id':[active_id], 'search_default_month':1,'search_default_user':1,'group_by_no_leaf':1,'group_by':[]}"
|
||||
res_model="account.invoice.report"
|
||||
src_model="res.partner"/>
|
||||
src_model="res.partner"
|
||||
view_mode="graph"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -163,10 +163,6 @@
|
||||
width: 100%; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr {
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.created_line, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr.created_line {
|
||||
cursor: default !important; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view tr.created_line .line_remove_button, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table tr.created_line .line_remove_button {
|
||||
cursor: pointer; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match table td {
|
||||
padding: 1px 8px;
|
||||
vertical-align: middle; }
|
||||
@@ -225,10 +221,14 @@
|
||||
padding-bottom: 3px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption {
|
||||
text-align: left;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
height: 26px;
|
||||
margin: 0 15px 4px 15px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption .partner_name {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption .tip_reconciliation_not_balanced {
|
||||
float: right;
|
||||
padding-right: 7px; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption button {
|
||||
float: right;
|
||||
position: relative;
|
||||
@@ -238,8 +238,7 @@
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > span, .openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view caption > input {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
/* meh */
|
||||
font-weight: bold; }
|
||||
/* meh */ }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .accounting_view td.cell_credit {
|
||||
border-left: 1px solid #000; }
|
||||
.openerp .oe_bank_statement_reconciliation .oe_bank_statement_reconciliation_line .match .match_controls {
|
||||
|
||||
@@ -267,14 +267,6 @@ $aestetic_animation_speed: 300ms;
|
||||
|
||||
tr {
|
||||
cursor: pointer;
|
||||
|
||||
&.created_line {
|
||||
cursor: default !important;
|
||||
|
||||
.line_remove_button {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
@@ -373,11 +365,19 @@ $aestetic_animation_speed: 300ms;
|
||||
|
||||
caption {
|
||||
text-align: left;
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
height: 26px;
|
||||
margin: 0 $actionColWidth 4px $actionColWidth;
|
||||
|
||||
.partner_name {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tip_reconciliation_not_balanced {
|
||||
float: right;
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
button {
|
||||
float: right;
|
||||
position: relative;
|
||||
@@ -390,7 +390,6 @@ $aestetic_animation_speed: 300ms;
|
||||
|
||||
> span, > input {
|
||||
position: relative; top: 7px; /* meh */
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1172,7 +1172,7 @@ openerp.account = function (instance) {
|
||||
var self = this;
|
||||
$.each(self.$(".tbody_matched_lines .bootstrap_popover"), function(){ $(this).popover('destroy') });
|
||||
self.$(".tbody_matched_lines").empty();
|
||||
|
||||
|
||||
_(self.get("mv_lines_selected")).each(function(line){
|
||||
var $line = $(QWeb.render("bank_statement_reconciliation_move_line", {line: line, selected: true}));
|
||||
self.bindPopoverTo($line.find(".line_info_button"));
|
||||
@@ -1189,7 +1189,7 @@ openerp.account = function (instance) {
|
||||
|
||||
_(self.getCreatedLines()).each(function(line){
|
||||
var $line = $(QWeb.render("bank_statement_reconciliation_created_line", {line: line}));
|
||||
$line.find(".line_remove_button").click(function(){ self.removeLine($(this).closest(".created_line")) });
|
||||
$line.click(function(){ self.removeLine($(this)) });
|
||||
self.$(".tbody_created_lines").append($line);
|
||||
if (line.no_remove_action) {
|
||||
// Then the previous line's remove button deletes this line too
|
||||
@@ -1241,50 +1241,62 @@ openerp.account = function (instance) {
|
||||
|
||||
/** Properties changed */
|
||||
|
||||
// Updates the validation button and the "open balance" line
|
||||
// Updates the validation button, the "open balance" line and the partial reconciliation sign
|
||||
balanceChanged: function() {
|
||||
var self = this;
|
||||
var balance = self.get("balance");
|
||||
|
||||
// 'reset' the widget to invalid state
|
||||
self.is_valid = false;
|
||||
self.$(".tip_reconciliation_not_balanced").show();
|
||||
self.$(".tbody_open_balance").empty();
|
||||
// Special case hack : no identified partner
|
||||
if (self.st_line.has_no_partner) {
|
||||
if (Math.abs(balance).toFixed(3) === "0.000") {
|
||||
self.$(".button_ok").addClass("btn-primary");
|
||||
self.$(".button_ok").removeAttr("disabled");
|
||||
self.$(".button_ok").text("OK");
|
||||
self.is_valid = true;
|
||||
self.$(".button_ok").text("OK").removeClass("btn-primary").attr("disabled", "disabled");
|
||||
|
||||
// Find out if the counterpart is lower than, equal or greater than the transaction being reconciled
|
||||
var balance_type = undefined;
|
||||
if (Math.abs(self.get("balance")).toFixed(3) === "0.000") balance_type = "equal";
|
||||
else if (self.get("balance") * self.st_line.amount > 0) balance_type = "greater";
|
||||
else if (self.get("balance") * self.st_line.amount < 0) balance_type = "lower";
|
||||
|
||||
// Adjust to different cases
|
||||
if (balance_type === "equal") {
|
||||
displayValidState(true);
|
||||
} else if (balance_type === "greater") {
|
||||
createOpenBalance("Create Write-off");
|
||||
} else if (balance_type === "lower") {
|
||||
if (self.st_line.has_no_partner) {
|
||||
createOpenBalance("Choose counterpart");
|
||||
} else {
|
||||
self.$(".button_ok").removeClass("btn-primary");
|
||||
self.$(".button_ok").attr("disabled", "disabled");
|
||||
self.$(".button_ok").text("OK");
|
||||
self.is_valid = false;
|
||||
var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : "");
|
||||
var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : "");
|
||||
var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {
|
||||
debit: debit,
|
||||
credit: credit,
|
||||
account_code: self.map_account_id_code[self.st_line.open_balance_account_id]
|
||||
}));
|
||||
$line.find('.js_open_balance')[0].innerHTML = _t("Choose counterpart");
|
||||
self.$(".tbody_open_balance").append($line);
|
||||
displayValidState(false, "Keep open");
|
||||
createOpenBalance("Open balance");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Math.abs(balance).toFixed(3) === "0.000") {
|
||||
self.$(".button_ok").addClass("btn-primary");
|
||||
self.$(".button_ok").text("OK");
|
||||
} else {
|
||||
self.$(".button_ok").removeClass("btn-primary");
|
||||
self.$(".button_ok").text("Keep open");
|
||||
var debit = (balance > 0 ? self.formatCurrency(balance, self.st_line.currency_id) : "");
|
||||
var credit = (balance < 0 ? self.formatCurrency(-1*balance, self.st_line.currency_id) : "");
|
||||
|
||||
// Show or hide partial reconciliation
|
||||
if (self.get("mv_lines_selected").length > 0) {
|
||||
var propose_partial = self.getCreatedLines().length === 0 && self.get("mv_lines_selected").length === 1 && balance_type === "greater" && ! self.get("mv_lines_selected")[0].partial_reconcile;
|
||||
self.get("mv_lines_selected")[0].propose_partial_reconcile = propose_partial;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
}
|
||||
|
||||
function displayValidState(higlight_ok_button, ok_button_text) {
|
||||
self.is_valid = true;
|
||||
self.$(".tip_reconciliation_not_balanced").hide();
|
||||
self.$(".button_ok").removeAttr("disabled");
|
||||
if (higlight_ok_button) self.$(".button_ok").addClass("btn-primary");
|
||||
if (ok_button_text !== undefined) self.$(".button_ok").text(ok_button_text)
|
||||
}
|
||||
|
||||
function createOpenBalance(name) {
|
||||
var balance = self.get("balance");
|
||||
var amount = self.formatCurrency(Math.abs(balance), self.st_line.currency_id);
|
||||
var $line = $(QWeb.render("bank_statement_reconciliation_line_open_balance", {
|
||||
debit: debit,
|
||||
credit: credit,
|
||||
debit: balance > 0 ? amount : "",
|
||||
credit: balance < 0 ? amount : "",
|
||||
account_code: self.map_account_id_code[self.st_line.open_balance_account_id]
|
||||
}));
|
||||
self.$(".tbody_open_balance").append($line);
|
||||
if (name !== undefined)
|
||||
$line.find(".cell_label").text(name);
|
||||
self.$(".tbody_open_balance").empty().append($line);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1430,6 +1442,8 @@ openerp.account = function (instance) {
|
||||
line_created_being_edited[index].amount = Math.round(val.amount*rounding)/rounding;
|
||||
line_created_being_edited[index].amount_str = self.formatCurrency(Math.abs(val.amount), val.currency_id);
|
||||
}
|
||||
if (val.amount_with_tax)
|
||||
line_created_being_edited[index].amount_with_tax = Math.round(val.amount_with_tax*rounding)/rounding;
|
||||
});
|
||||
self.set("line_created_being_edited", line_created_being_edited);
|
||||
self.createdLinesChanged(); // TODO For some reason, previous line doesn't trigger change handler
|
||||
@@ -1527,20 +1541,8 @@ openerp.account = function (instance) {
|
||||
});
|
||||
// Dealing with floating-point
|
||||
balance = Math.round(balance*1000)/1000;
|
||||
|
||||
self.set("balance", balance);
|
||||
|
||||
// Propose partial reconciliation if necessary
|
||||
if (lines_selected_num === 1 &&
|
||||
self.st_line.amount * balance > 0 &&
|
||||
self.st_line.amount * (mv_lines_selected[0].debit - mv_lines_selected[0].credit) < 0 &&
|
||||
! mv_lines_selected[0].partial_reconcile) {
|
||||
|
||||
mv_lines_selected[0].propose_partial_reconcile = true;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
} else if (lines_selected_num === 1) {
|
||||
mv_lines_selected[0].propose_partial_reconcile = false;
|
||||
self.updateAccountingViewMatchedLines();
|
||||
}
|
||||
},
|
||||
|
||||
// Loads move lines according to the widget's state
|
||||
@@ -1627,7 +1629,7 @@ openerp.account = function (instance) {
|
||||
var dict = {};
|
||||
|
||||
dict['account_id'] = this.st_line.open_balance_account_id;
|
||||
dict['name'] = _t("Open balance");
|
||||
dict['name'] = this.st_line.name + ' : ' + _t("Open balance");
|
||||
if (balance > 0) dict['debit'] = balance;
|
||||
if (balance < 0) dict['credit'] = -1*balance;
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
<table class="accounting_view">
|
||||
<caption>
|
||||
<button class="button_ok btn btn-default btn-sm"></button>
|
||||
<span class="tip_reconciliation_not_balanced">You must balance the reconciliation</span>
|
||||
<span t-if="! line.has_no_partner" class="partner_name">
|
||||
<t t-esc="line.partner_name"/>
|
||||
<span class="change_partner glyphicon glyphicon-pencil"></span>
|
||||
@@ -175,7 +176,7 @@
|
||||
|
||||
<t t-name="bank_statement_reconciliation_created_line">
|
||||
<tr class="created_line" t-att-data-lineid="line.id">
|
||||
<td class="cell_action"><t t-if="! line.no_remove_action"><span class="line_remove_button glyphicon glyphicon-remove"></span></t></td>
|
||||
<td class="cell_action"><t t-if="! line.no_remove_action"><span class="glyphicon glyphicon-remove"></span></t></td>
|
||||
<td class="cell_account_code"><t t-esc="line.account_num"/></td>
|
||||
<td class="cell_due_date"></td>
|
||||
<td class="cell_label"><t t-esc="line.label"/></td>
|
||||
@@ -190,7 +191,7 @@
|
||||
<td class="cell_action"><span class="toggle_create glyphicon glyphicon-play"></span></td>
|
||||
<td class="cell_account_code"><t t-esc="account_code"/></td>
|
||||
<td class="cell_due_date"></td>
|
||||
<td class="cell_label js_open_balance">Open balance</td>
|
||||
<td class="cell_label">Open balance</td>
|
||||
<td class="cell_debit"><t t-esc="debit"/></td>
|
||||
<td class="cell_credit"><t t-esc="credit"/></td>
|
||||
<td class="cell_info_popover"></td>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from openerp.tests.common import TransactionCase
|
||||
import time
|
||||
|
||||
class TestReconciliation(TransactionCase):
|
||||
"""Tests for reconciliation (account.tax)
|
||||
@@ -36,7 +37,8 @@ class TestReconciliation(TransactionCase):
|
||||
'currency_id': self.currency_swiss_id,
|
||||
'name': 'invoice to client',
|
||||
'account_id': self.account_rcv_id,
|
||||
'type': 'out_invoice'
|
||||
'type': 'out_invoice',
|
||||
'date_invoice': time.strftime('%Y')+'-07-01', # to use USD rate rateUSDbis
|
||||
})
|
||||
self.account_invoice_line_model.create(cr, uid, {'product_id': self.product_id,
|
||||
'quantity': 1,
|
||||
@@ -49,14 +51,18 @@ class TestReconciliation(TransactionCase):
|
||||
invoice_record = self.account_invoice_model.browse(cr, uid, [invoice_id])
|
||||
|
||||
#we pay half of it on a journal with currency in dollar (bank statement)
|
||||
bank_stmt_id = self.acc_bank_stmt_model.create(cr, uid, {'journal_id': self.bank_journal_usd_id,})
|
||||
bank_stmt_id = self.acc_bank_stmt_model.create(cr, uid, {
|
||||
'journal_id': self.bank_journal_usd_id,
|
||||
'date': time.strftime('%Y')+'-07-15',
|
||||
})
|
||||
|
||||
bank_stmt_line_id = self.acc_bank_stmt_line_model.create(cr, uid, {'name': 'half payment',
|
||||
'statement_id': bank_stmt_id,
|
||||
'partner_id': self.partner_agrolait_id,
|
||||
'amount': 42,
|
||||
'amount_currency': 50,
|
||||
'currency_id': self.currency_swiss_id,})
|
||||
'currency_id': self.currency_swiss_id,
|
||||
'date': time.strftime('%Y')+'-07-15',})
|
||||
|
||||
#reconcile the payment with the invoice
|
||||
for l in invoice_record.move_id.line_id:
|
||||
@@ -103,7 +109,8 @@ class TestReconciliation(TransactionCase):
|
||||
'currency_id': self.currency_swiss_id,
|
||||
'name': 'invoice to client',
|
||||
'account_id': self.account_rcv_id,
|
||||
'type': 'in_invoice'
|
||||
'type': 'in_invoice',
|
||||
'date_invoice': time.strftime('%Y')+'-07-01',
|
||||
})
|
||||
self.account_invoice_line_model.create(cr, uid, {'product_id': self.product_id,
|
||||
'quantity': 1,
|
||||
@@ -116,14 +123,18 @@ class TestReconciliation(TransactionCase):
|
||||
invoice_record = self.account_invoice_model.browse(cr, uid, [invoice_id])
|
||||
|
||||
#we pay half of it on a journal with currency in dollar (bank statement)
|
||||
bank_stmt_id = self.acc_bank_stmt_model.create(cr, uid, {'journal_id': self.bank_journal_usd_id,})
|
||||
bank_stmt_id = self.acc_bank_stmt_model.create(cr, uid, {
|
||||
'journal_id': self.bank_journal_usd_id,
|
||||
'date': time.strftime('%Y')+'-07-15',
|
||||
})
|
||||
|
||||
bank_stmt_line_id = self.acc_bank_stmt_line_model.create(cr, uid, {'name': 'half payment',
|
||||
'statement_id': bank_stmt_id,
|
||||
'partner_id': self.partner_agrolait_id,
|
||||
'amount': -42,
|
||||
'amount_currency': -50,
|
||||
'currency_id': self.currency_swiss_id,})
|
||||
'currency_id': self.currency_swiss_id,
|
||||
'date': time.strftime('%Y')+'-07-15',})
|
||||
|
||||
#reconcile the payment with the invoice
|
||||
for l in invoice_record.move_id.line_id:
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<td class="text-right">
|
||||
<span t-field="l.price_unit"/>
|
||||
</td>
|
||||
<td groups="sale.group_discount_per_so_line"><span t-field="l.discount"/></td>
|
||||
<td class="text-right" groups="sale.group_discount_per_so_line"><span t-field="l.discount"/></td>
|
||||
<td>
|
||||
<span t-esc="', '.join(map(lambda x: x.name, l.invoice_line_tax_id))"/>
|
||||
</td>
|
||||
@@ -142,7 +142,7 @@
|
||||
<p t-if="o.payment_term">
|
||||
<span t-field="o.payment_term.note"/>
|
||||
</p>
|
||||
<p t-if="o.fiscal_position and o.fiscal_position.note">
|
||||
<p t-if="o.fiscal_position.note">
|
||||
<strong>Fiscal Position Remark:</strong>
|
||||
<span t-field="o.fiscal_position.note"/>
|
||||
</p>
|
||||
|
||||
@@ -51,7 +51,7 @@ class account_chart(osv.osv_memory):
|
||||
FROM account_period p
|
||||
LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id)
|
||||
WHERE f.id = %s
|
||||
ORDER BY p.date_start ASC
|
||||
ORDER BY p.date_start ASC, p.special DESC
|
||||
LIMIT 1) AS period_start
|
||||
UNION ALL
|
||||
SELECT * FROM (SELECT p.id
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<button name="%(action_sales_order)d" string="Sales Orders"
|
||||
type="action"
|
||||
class="oe_link"
|
||||
context="{'default_partner_id': [partner_id], 'search_default_project_id': [active_id],'default_project_id': [active_id]}"
|
||||
context="{'default_partner_id': [partner_id], 'search_default_project_id': [active_id],'default_project_id': [active_id], 'default_pricelist_id': pricelist_id}"
|
||||
/>
|
||||
</td>
|
||||
</tr><tr>
|
||||
@@ -198,6 +198,7 @@
|
||||
<field name="name">account.analytic.account.list.contract</field>
|
||||
<field name="model">account.analytic.account</field>
|
||||
<field name="inherit_id" ref="analytic.view_account_analytic_account_list"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="date_start" position="before">
|
||||
<field name="last_invoice_date"/>
|
||||
|
||||
@@ -442,7 +442,9 @@ class sale_order_line(osv.osv):
|
||||
if ids:
|
||||
sale_line = self.browse(cr, uid, ids[0], context=context)
|
||||
for line in inv_line_obj.browse(cr, uid, create_ids, context=context):
|
||||
rec = acct_anal_def_obj.account_get(cr, uid, line.product_id.id, sale_line.order_id.partner_id.id, uid, time.strftime('%Y-%m-%d'), context)
|
||||
rec = acct_anal_def_obj.account_get(cr, uid, line.product_id.id,
|
||||
sale_line.order_id.partner_id.id, uid, time.strftime('%Y-%m-%d'),
|
||||
sale_line.order_id.company_id.id, context=context)
|
||||
|
||||
if rec:
|
||||
inv_line_obj.write(cr, uid, [line.id], {'analytics_id': rec.analytics_id.id}, context=context)
|
||||
|
||||
@@ -50,14 +50,9 @@ class account_invoice_line(osv.osv):
|
||||
return res
|
||||
if type in ('in_invoice','in_refund'):
|
||||
product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context)
|
||||
if type == 'in_invoice':
|
||||
oa = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id
|
||||
if not oa:
|
||||
oa = product_obj.categ_id.property_stock_account_input_categ and product_obj.categ_id.property_stock_account_input_categ.id
|
||||
else:
|
||||
oa = product_obj.property_stock_account_output and product_obj.property_stock_account_output.id
|
||||
if not oa:
|
||||
oa = product_obj.categ_id.property_stock_account_output_categ and product_obj.categ_id.property_stock_account_output_categ.id
|
||||
oa = product_obj.property_stock_account_input and product_obj.property_stock_account_input.id
|
||||
if not oa:
|
||||
oa = product_obj.categ_id.property_stock_account_input_categ and product_obj.categ_id.property_stock_account_input_categ.id
|
||||
if oa:
|
||||
fpos = fposition_id and fiscal_pool.browse(cr, uid, fposition_id, context=context) or False
|
||||
a = fiscal_pool.map_account(cr, uid, fpos, oa)
|
||||
@@ -82,7 +77,7 @@ class account_invoice_line(osv.osv):
|
||||
inv = i_line.invoice_id
|
||||
company_currency = inv.company_id.currency_id.id
|
||||
|
||||
if i_line.product_id and i_line.product_id.valuation == 'real_time':
|
||||
if i_line.product_id.type != 'service' and i_line.product_id.valuation == 'real_time':
|
||||
# debit account dacc will be the output account
|
||||
# first check the product, if empty check the category
|
||||
dacc = i_line.product_id.property_stock_account_output and i_line.product_id.property_stock_account_output.id
|
||||
|
||||
@@ -21,42 +21,33 @@
|
||||
|
||||
from openerp.osv import osv
|
||||
|
||||
#----------------------------------------------------------
|
||||
# Stock Picking
|
||||
#----------------------------------------------------------
|
||||
class stock_move(osv.Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
def _get_invoice_line_vals(self, cr, uid, move, partner, inv_type, context=None):
|
||||
""" Add a reference to the stock.move in the invoice line
|
||||
|
||||
In anglo-saxon the price for COGS should be taken from stock.move
|
||||
if possible (fallback on standard_price)
|
||||
"""
|
||||
res = super(stock_move, self)._get_invoice_line_vals(cr, uid, move, partner, inv_type, context=context)
|
||||
res.update({
|
||||
'move_id': move.id,
|
||||
})
|
||||
return res
|
||||
|
||||
class stock_picking(osv.osv):
|
||||
_inherit = "stock.picking"
|
||||
_description = "Picking List"
|
||||
|
||||
def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id,
|
||||
invoice_vals, context=None):
|
||||
"""Overwrite to add move_id reference"""
|
||||
res = super(stock_picking, self)._prepare_invoice_line(cr, uid, group, picking, move_line, invoice_id, invoice_vals, context=context)
|
||||
res.update({
|
||||
'move_id': move_line.id,
|
||||
})
|
||||
return res
|
||||
|
||||
def action_invoice_create(self, cr, uid, ids, journal_id=False,
|
||||
group=False, type='out_invoice', context=None):
|
||||
'''Return ids of created invoices for the pickings'''
|
||||
res = super(stock_picking,self).action_invoice_create(cr, uid, ids, journal_id, group, type, context=context)
|
||||
if type == 'in_refund':
|
||||
if type in ('in_invoice', 'in_refund'):
|
||||
for inv in self.pool.get('account.invoice').browse(cr, uid, res, context=context):
|
||||
for ol in inv.invoice_line:
|
||||
if ol.product_id:
|
||||
oa = ol.product_id.property_stock_account_output and ol.product_id.property_stock_account_output.id
|
||||
if not oa:
|
||||
oa = ol.product_id.categ_id.property_stock_account_output_categ and ol.product_id.categ_id.property_stock_account_output_categ.id
|
||||
if oa:
|
||||
fpos = ol.invoice_id.fiscal_position or False
|
||||
a = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, oa)
|
||||
self.pool.get('account.invoice.line').write(cr, uid, [ol.id], {'account_id': a})
|
||||
|
||||
elif type == 'in_invoice':
|
||||
for inv in self.pool.get('account.invoice').browse(cr, uid, res, context=context):
|
||||
for ol in inv.invoice_line:
|
||||
if ol.product_id:
|
||||
if ol.product_id.type != 'service':
|
||||
oa = ol.product_id.property_stock_account_input and ol.product_id.property_stock_account_input.id
|
||||
if not oa:
|
||||
oa = ol.product_id.categ_id.property_stock_account_input_categ and ol.product_id.categ_id.property_stock_account_input_categ.id
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
<field name="amount" position="after">
|
||||
<newline/>
|
||||
<field name="allow_check" invisible="1"/>
|
||||
<field name="amount_in_word" attrs="{'invisible':[('allow_check','!=',1)]}" nolabel="1" colspan="6"/>
|
||||
<field name="amount_in_word" attrs="{'invisible':[('allow_check','!=',True)]}" nolabel="1" colspan="6"/>
|
||||
<newline/>
|
||||
</field>
|
||||
<field name="number" position="replace">
|
||||
<field name="number" attrs="{'readonly':[('allow_check','!=',1)]}" />
|
||||
<field name="number" attrs="{'readonly':[('allow_check','!=',True)]}" />
|
||||
</field>
|
||||
<button name="proforma_voucher" position="after">
|
||||
<button name="print_check" icon="gtk-print" string="Print Check" type="object" attrs="{'invisible':['|',('allow_check','!=',1),('state','!=','posted') ]}" class="oe_highlight"/>
|
||||
<button name="print_check" icon="gtk-print" string="Print Check" type="object" attrs="{'invisible':['|',('allow_check','!=',True),('state','!=','posted') ]}" class="oe_highlight"/>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -24,6 +24,7 @@ _logger = logging.getLogger(__name__)
|
||||
def fragment_to_query_string(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(self, *a, **kw):
|
||||
kw.pop('debug', False)
|
||||
if not kw:
|
||||
return """<html><head><script>
|
||||
var l = window.location;
|
||||
|
||||
@@ -64,8 +64,8 @@ class res_partner(osv.osv):
|
||||
_inherit = "res.partner"
|
||||
|
||||
_columns = {
|
||||
'partner_latitude': fields.float('Geo Latitude'),
|
||||
'partner_longitude': fields.float('Geo Longitude'),
|
||||
'partner_latitude': fields.float('Geo Latitude', digits=(16, 5)),
|
||||
'partner_longitude': fields.float('Geo Longitude', digits=(16, 5)),
|
||||
'date_localization': fields.date('Geo Localization Date'),
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -32,7 +32,7 @@ def calendar_id2real_id(calendar_id=None, with_date=False):
|
||||
@param with_date: if a value is passed to this param it will return dates based on value of withdate + calendar_id
|
||||
@return: real event id
|
||||
"""
|
||||
if calendar_id and isinstance(calendar_id, (str, unicode)):
|
||||
if calendar_id and isinstance(calendar_id, (basestring)):
|
||||
res = calendar_id.split('-')
|
||||
if len(res) >= 2:
|
||||
real_id = res[0]
|
||||
@@ -46,7 +46,7 @@ def calendar_id2real_id(calendar_id=None, with_date=False):
|
||||
|
||||
|
||||
def get_real_ids(ids):
|
||||
if isinstance(ids, (str, int, long)):
|
||||
if isinstance(ids, (basestring, int, long)):
|
||||
return calendar_id2real_id(ids)
|
||||
|
||||
if isinstance(ids, (list, tuple)):
|
||||
@@ -625,14 +625,14 @@ class ir_model(osv.Model):
|
||||
_inherit = 'ir.model'
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context=None, load='_classic_read'):
|
||||
new_ids = isinstance(ids, (str, int, long)) and [ids] or ids
|
||||
new_ids = isinstance(ids, (basestring, int, long)) and [ids] or ids
|
||||
if context is None:
|
||||
context = {}
|
||||
data = super(ir_model, self).read(cr, uid, new_ids, fields=fields, context=context, load=load)
|
||||
if data:
|
||||
for val in data:
|
||||
val['id'] = calendar_id2real_id(val['id'])
|
||||
return isinstance(ids, (str, int, long)) and data[0] or data
|
||||
return isinstance(ids, (basestring, int, long)) and data[0] or data
|
||||
|
||||
|
||||
original_exp_report = openerp.service.report.exp_report
|
||||
@@ -1138,7 +1138,7 @@ class calendar_event(osv.Model):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
if isinstance(event_id, (str, int, long)):
|
||||
if isinstance(event_id, (basestring, int, long)):
|
||||
ids_to_browse = [event_id] # keep select for return
|
||||
else:
|
||||
ids_to_browse = event_id
|
||||
@@ -1220,7 +1220,7 @@ class calendar_event(osv.Model):
|
||||
comparers = [((itemgetter(col[1:]), -1) if col[0] == '-' else (itemgetter(col), 1)) for col in sort_params]
|
||||
ids = [r['id'] for r in sorted(result_data, cmp=comparer)]
|
||||
|
||||
if isinstance(event_id, (str, int, long)):
|
||||
if isinstance(event_id, (basestring, int, long)):
|
||||
return ids and ids[0] or False
|
||||
else:
|
||||
return ids
|
||||
@@ -1383,7 +1383,7 @@ class calendar_event(osv.Model):
|
||||
|
||||
@api.cr_uid_ids_context
|
||||
def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, **kwargs):
|
||||
if isinstance(thread_id, str):
|
||||
if isinstance(thread_id, basestring):
|
||||
thread_id = get_real_ids(thread_id)
|
||||
if context.get('default_date'):
|
||||
del context['default_date']
|
||||
@@ -1509,7 +1509,7 @@ class calendar_event(osv.Model):
|
||||
for arg in args:
|
||||
if arg[0] == 'id':
|
||||
for n, calendar_id in enumerate(arg[2]):
|
||||
if isinstance(calendar_id, str):
|
||||
if isinstance(calendar_id, basestring):
|
||||
arg[2][n] = calendar_id.split('-')[0]
|
||||
return super(calendar_event, self)._name_search(cr, user, name=name, args=args, operator=operator, context=context, limit=limit, name_get_uid=name_get_uid)
|
||||
|
||||
@@ -1528,7 +1528,7 @@ class calendar_event(osv.Model):
|
||||
self._set_date(cr, uid, values, id=ids[0], context=context)
|
||||
|
||||
for one_ids in ids:
|
||||
if isinstance(one_ids, (str, int, long)):
|
||||
if isinstance(one_ids, (basestring, int, long)):
|
||||
if len(str(one_ids).split('-')) == 1:
|
||||
ids = [int(one_ids)]
|
||||
else:
|
||||
@@ -1624,7 +1624,7 @@ class calendar_event(osv.Model):
|
||||
for f in EXTRAFIELDS:
|
||||
if fields and (f not in fields):
|
||||
fields2.append(f)
|
||||
if isinstance(ids, (str, int, long)):
|
||||
if isinstance(ids, (basestring, int, long)):
|
||||
select = [ids]
|
||||
else:
|
||||
select = ids
|
||||
@@ -1636,7 +1636,7 @@ class calendar_event(osv.Model):
|
||||
for calendar_id, real_id in select:
|
||||
res = real_data[real_id].copy()
|
||||
ls = calendar_id2real_id(calendar_id, with_date=res and res.get('duration', 0) > 0 and res.get('duration') or 1)
|
||||
if not isinstance(ls, (str, int, long)) and len(ls) >= 2:
|
||||
if not isinstance(ls, (basestring, int, long)) and len(ls) >= 2:
|
||||
res['start'] = ls[1]
|
||||
res['stop'] = ls[2]
|
||||
|
||||
@@ -1672,7 +1672,7 @@ class calendar_event(osv.Model):
|
||||
for k in EXTRAFIELDS:
|
||||
if (k in r) and (fields and (k not in fields)):
|
||||
del r[k]
|
||||
if isinstance(ids, (str, int, long)):
|
||||
if isinstance(ids, (basestring, int, long)):
|
||||
return result and result[0] or False
|
||||
return result
|
||||
|
||||
@@ -1711,7 +1711,7 @@ class mail_message(osv.Model):
|
||||
convert the search on real ids in the case it was asked on virtual ids, then call super()
|
||||
'''
|
||||
for index in range(len(args)):
|
||||
if args[index][0] == "res_id" and isinstance(args[index][2], str):
|
||||
if args[index][0] == "res_id" and isinstance(args[index][2], basestring):
|
||||
args[index][2] = get_real_ids(args[index][2])
|
||||
return super(mail_message, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
|
||||
|
||||
@@ -1733,7 +1733,7 @@ class ir_attachment(osv.Model):
|
||||
convert the search on real ids in the case it was asked on virtual ids, then call super()
|
||||
'''
|
||||
for index in range(len(args)):
|
||||
if args[index][0] == "res_id" and isinstance(args[index][2], str):
|
||||
if args[index][0] == "res_id" and isinstance(args[index][2], basestring):
|
||||
args[index][2] = get_real_ids(args[index][2])
|
||||
return super(ir_attachment, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
|
||||
|
||||
@@ -1741,7 +1741,7 @@ class ir_attachment(osv.Model):
|
||||
'''
|
||||
when posting an attachment (new or not), convert the virtual ids in real ids.
|
||||
'''
|
||||
if isinstance(vals.get('res_id'), str):
|
||||
if isinstance(vals.get('res_id'), basestring):
|
||||
vals['res_id'] = get_real_ids(vals.get('res_id'))
|
||||
return super(ir_attachment, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ class crm_lead(format_address, osv.osv):
|
||||
""" When changing the user, also set a team_id or restrict team id
|
||||
to the ones user_id is member of. """
|
||||
team_id = self._get_default_team_id(cr, uid, context=context)
|
||||
if user_id and not team_id:
|
||||
if user_id and not team_id and self.pool['res.users'].has_group(cr, uid, 'base.group_multi_salesteams'):
|
||||
team_ids = self.pool.get('crm.team').search(cr, uid, ['|', ('user_id', '=', user_id), ('member_ids', '=', user_id)], context=context)
|
||||
if team_ids:
|
||||
team_id = team_ids[0]
|
||||
|
||||
@@ -30,8 +30,9 @@ class res_partner(osv.osv):
|
||||
# the user may not have access rights for opportunities or meetings
|
||||
try:
|
||||
for partner in self.browse(cr, uid, ids, context):
|
||||
opp_ids = self.pool['crm.lead'].search(cr, uid, [('partner_id', '=', partner.id), ('type', '=', 'opportunity'), ('probability', '<', '100')], context=context)
|
||||
res[partner.id] = {
|
||||
'opportunity_count': len(partner.opportunity_ids),
|
||||
'opportunity_count': len(opp_ids),
|
||||
'meeting_count': len(partner.meeting_ids),
|
||||
}
|
||||
except:
|
||||
|
||||
@@ -85,8 +85,8 @@ class res_partner(osv.osv):
|
||||
class crm_lead(osv.osv):
|
||||
_inherit = "crm.lead"
|
||||
_columns = {
|
||||
'partner_latitude': fields.float('Geo Latitude'),
|
||||
'partner_longitude': fields.float('Geo Longitude'),
|
||||
'partner_latitude': fields.float('Geo Latitude', digits=(16, 5)),
|
||||
'partner_longitude': fields.float('Geo Longitude', digits=(16, 5)),
|
||||
'partner_assigned_id': fields.many2one('res.partner', 'Assigned Partner',track_visibility='onchange' , help="Partner this case has been forwarded/assigned to.", select=True),
|
||||
'date_assign': fields.date('Assignation Date', help="Last date this case was forwarded/assigned to a partner"),
|
||||
}
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
<separator string="Partner Activation" colspan="2"/>
|
||||
<field name="grade_id" widget="selection"/>
|
||||
<field name="activation" widget="selection"/>
|
||||
<field name="assigned_partner_id"/>
|
||||
<field name="partner_weight"/>
|
||||
</group>
|
||||
<group>
|
||||
|
||||
@@ -237,9 +237,9 @@
|
||||
<div>
|
||||
<field name="weight" class="oe_inline"/>
|
||||
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
|
||||
<field name="number_of_packages"/>
|
||||
</div>
|
||||
<field name="weight_net" groups="base.group_no_one"/>
|
||||
<field name="number_of_packages"/>
|
||||
</group>
|
||||
</group>
|
||||
</xpath>
|
||||
@@ -276,12 +276,14 @@
|
||||
<field name="inherit_id" ref="stock.view_move_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='main_grp']" position="inside">
|
||||
<label for="weight" string="Weight"/>
|
||||
<div>
|
||||
<field name="weight" class="oe_inline"/>
|
||||
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="weight_net" groups="base.group_no_one" class="oe_inline"/>
|
||||
<group>
|
||||
<label for="weight"/>
|
||||
<div>
|
||||
<field name="weight" nolabel="1" class="oe_inline"/>
|
||||
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="weight_net" groups="base.group_no_one"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -88,4 +88,4 @@ class sale_order(osv.Model):
|
||||
'price_unit': grid_obj.get_price(cr, uid, grid.id, order, time.strftime('%Y-%m-%d'), context),
|
||||
'tax_id': [(6, 0, taxes_ids)],
|
||||
'is_delivery': True
|
||||
})
|
||||
}, context=context)
|
||||
|
||||
@@ -471,11 +471,14 @@ class email_template(osv.osv):
|
||||
results = dict()
|
||||
for template, template_res_ids in templates_to_res_ids.iteritems():
|
||||
# generate fields value for all res_ids linked to the current template
|
||||
ctx = context.copy()
|
||||
if template.lang:
|
||||
ctx['lang'] = template._context.get('lang')
|
||||
for field in fields:
|
||||
generated_field_values = self.render_template_batch(
|
||||
cr, uid, getattr(template, field), template.model, template_res_ids,
|
||||
post_process=(field == 'body_html'),
|
||||
context=context)
|
||||
context=ctx)
|
||||
for res_id, field_value in generated_field_values.iteritems():
|
||||
results.setdefault(res_id, dict())[field] = field_value
|
||||
# compute recipients
|
||||
@@ -503,13 +506,9 @@ class email_template(osv.osv):
|
||||
if template.report_template:
|
||||
for res_id in template_res_ids:
|
||||
attachments = []
|
||||
report_name = self.render_template(cr, uid, template.report_name, template.model, res_id, context=context)
|
||||
report_name = self.render_template(cr, uid, template.report_name, template.model, res_id, context=ctx)
|
||||
report = report_xml_pool.browse(cr, uid, template.report_template.id, context)
|
||||
report_service = report.report_name
|
||||
# Ensure report is rendered using template's language
|
||||
ctx = context.copy()
|
||||
if template.lang:
|
||||
ctx['lang'] = self.render_template_batch(cr, uid, template.lang, template.model, [res_id], context)[res_id] # take 0 ?
|
||||
|
||||
if report.report_type in ['qweb-html', 'qweb-pdf']:
|
||||
result, format = self.pool['report'].get_pdf(cr, uid, [res_id], report_service, context=ctx), 'pdf'
|
||||
|
||||
@@ -129,7 +129,7 @@ class mail_compose_message(osv.TransientModel):
|
||||
email_template = self.pool.get('email.template')
|
||||
ir_model_pool = self.pool.get('ir.model')
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
model_ids = ir_model_pool.search(cr, uid, [('model', '=', record.model)], context=context)
|
||||
model_ids = ir_model_pool.search(cr, uid, [('model', '=', record.model or 'mail.message')], context=context)
|
||||
model_id = model_ids and model_ids[0] or False
|
||||
model_name = ''
|
||||
if model_id:
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<field name="name">Goal Form</field>
|
||||
<field name="model">gamification.goal</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Goal">
|
||||
<form string="Goal" create="false">
|
||||
<header>
|
||||
<button string="Start goal" type="object" name="action_start" states="draft" class="oe_highlight"/>
|
||||
|
||||
|
||||
@@ -624,6 +624,8 @@ class google_calendar(osv.AbstractModel):
|
||||
new_google_internal_event_id = False
|
||||
source_event_record = ev_obj.browse(cr, uid, att.event_id.recurrent_id, context)
|
||||
source_attendee_record_id = att_obj.search(cr, uid, [('partner_id', '=', myPartnerID), ('event_id', '=', source_event_record.id)], context=context)
|
||||
if not source_attendee_record_id:
|
||||
continue
|
||||
source_attendee_record = att_obj.browse(cr, uid, source_attendee_record_id, context)[0]
|
||||
|
||||
if att.event_id.recurrent_id_date and source_event_record.allday and source_attendee_record.google_internal_event_id:
|
||||
@@ -665,9 +667,9 @@ class google_calendar(osv.AbstractModel):
|
||||
registry = openerp.modules.registry.RegistryManager.get(request.session.db)
|
||||
with registry.cursor() as cur:
|
||||
self.pool['res.users'].write(cur, uid, [uid], {'google_calendar_last_sync_date': False}, context=context)
|
||||
error_key = simplejson.loads(e.read())
|
||||
error_key = simplejson.loads(str(e))
|
||||
error_key = error_key.get('error', {}).get('message', 'nc')
|
||||
error_msg = "Google are lost... the next synchro will be a full synchro. \n\n %s" % error_key
|
||||
error_msg = "Google is lost... the next synchro will be a full synchro. \n\n %s" % error_key
|
||||
raise self.pool.get('res.config.settings').get_config_warning(cr, _(error_msg), context=context)
|
||||
|
||||
my_google_att_ids = att_obj.search(cr, uid, [
|
||||
@@ -818,7 +820,8 @@ class google_calendar(osv.AbstractModel):
|
||||
res = self.update_from_google(cr, uid, parent_event, event.GG.event, "copy", context)
|
||||
else:
|
||||
parent_oe_id = event_to_synchronize[base_event][0][1].OE.event_id
|
||||
calendar_event.unlink(cr, uid, "%s-%s" % (parent_oe_id, new_google_event_id), can_be_deleted=True, context=context)
|
||||
if parent_oe_id:
|
||||
calendar_event.unlink(cr, uid, "%s-%s" % (parent_oe_id, new_google_event_id), can_be_deleted=True, context=context)
|
||||
|
||||
elif isinstance(actToDo, Delete):
|
||||
if actSrc == 'GG':
|
||||
|
||||
@@ -13,8 +13,8 @@ class calendar_config_settings(osv.TransientModel):
|
||||
def set_calset(self,cr,uid,ids,context=None) :
|
||||
params = self.pool['ir.config_parameter']
|
||||
myself = self.browse(cr,uid,ids[0],context=context)
|
||||
params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id or '', groups=['base.group_system'], context=None)
|
||||
params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret or '', groups=['base.group_system'], context=None)
|
||||
params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id.strip() or '', groups=['base.group_system'], context=None)
|
||||
params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret.strip() or '', groups=['base.group_system'], context=None)
|
||||
|
||||
|
||||
def get_default_all(self,cr,uid,ids,context=None):
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="employee" string="Employee" context="{'group_by':'employee_id'}"/>
|
||||
<separator/>
|
||||
<filter name="name" string="Month" context="{'group_by':'name'}"/>
|
||||
<filter name="groupby_name" string="Month" context="{'group_by':'name'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -316,9 +316,13 @@ class hr_applicant(osv.Model):
|
||||
return {'value': {'department_id': department_id, 'user_id': user_id}}
|
||||
|
||||
def onchange_department_id(self, cr, uid, ids, department_id=False, stage_id=False, context=None):
|
||||
values = {}
|
||||
if not stage_id:
|
||||
stage_id = self.stage_find(cr, uid, [], department_id, [('fold', '=', False)], context=context)
|
||||
return {'value': {'stage_id': stage_id}}
|
||||
values['stage_id'] = self.stage_find(cr, uid, [], department_id, [('fold', '=', False)], context=context)
|
||||
if department_id:
|
||||
department = self.pool['hr.department'].browse(cr, uid, department_id, context=context)
|
||||
values['company_id'] = department.company_id.id
|
||||
return {'value': values}
|
||||
|
||||
def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
|
||||
data = {'partner_phone': False,
|
||||
|
||||
@@ -39,7 +39,7 @@ class hr_timesheet_report(osv.osv):
|
||||
def _from(self):
|
||||
from_str = """
|
||||
account_analytic_line as aal
|
||||
left join hr_analytic_timesheet as hat ON (hat.line_id=aal.id)
|
||||
inner join hr_analytic_timesheet as hat ON (hat.line_id=aal.id)
|
||||
"""
|
||||
return from_str
|
||||
|
||||
|
||||
@@ -93,29 +93,41 @@ class StyleStack:
|
||||
'left': TXT_ALIGN_LT,
|
||||
'right': TXT_ALIGN_RT,
|
||||
'center': TXT_ALIGN_CT,
|
||||
'_order': 1,
|
||||
},
|
||||
'underline': {
|
||||
'off': TXT_UNDERL_OFF,
|
||||
'on': TXT_UNDERL_ON,
|
||||
'double': TXT_UNDERL2_ON,
|
||||
# must be issued after 'size' command
|
||||
# because ESC ! resets ESC -
|
||||
'_order': 10,
|
||||
},
|
||||
'bold': {
|
||||
'off': TXT_BOLD_OFF,
|
||||
'on': TXT_BOLD_ON,
|
||||
# must be issued after 'size' command
|
||||
# because ESC ! resets ESC E
|
||||
'_order': 10,
|
||||
},
|
||||
'font': {
|
||||
'a': TXT_FONT_A,
|
||||
'b': TXT_FONT_B,
|
||||
# must be issued after 'size' command
|
||||
# because ESC ! resets ESC M
|
||||
'_order': 10,
|
||||
},
|
||||
'size': {
|
||||
'normal': TXT_NORMAL,
|
||||
'double-height': TXT_2HEIGHT,
|
||||
'double-width': TXT_2WIDTH,
|
||||
'double': TXT_DOUBLE,
|
||||
'_order': 1,
|
||||
},
|
||||
'color': {
|
||||
'black': TXT_COLOR_BLACK,
|
||||
'red': TXT_COLOR_RED,
|
||||
'_order': 1,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -169,7 +181,10 @@ class StyleStack:
|
||||
def to_escpos(self):
|
||||
""" converts the current style to an escpos command string """
|
||||
cmd = ''
|
||||
for style in self.cmds:
|
||||
# Sort commands because some commands affect others (see _order attributes above)
|
||||
ordered_cmds = self.cmds.keys()
|
||||
ordered_cmds.sort(lambda x, y: cmp(self.cmds[x]['_order'], self.cmds[y]['_order']))
|
||||
for style in ordered_cmds:
|
||||
cmd += self.cmds[style][self.get(style)]
|
||||
return cmd
|
||||
|
||||
|
||||
@@ -26,39 +26,49 @@
|
||||
'description': """
|
||||
Swiss localization
|
||||
==================
|
||||
**Multilang swiss STERCHI account chart and taxes**
|
||||
**Author:** Camptocamp SA
|
||||
|
||||
**Financial contributors:** Prisme Solutions Informatique SA, Quod SA
|
||||
**Multilang Swiss PME/KMU 2015 account chart and taxes**
|
||||
|
||||
**Translation contributors:** brain-tec AG, Agile Business Group
|
||||
**Author:** Camptocamp SA
|
||||
|
||||
**This release will introduce major changes to l10n_ch.**
|
||||
**Financial contributors:** Prisme Solutions Informatique SA, Quod SA
|
||||
|
||||
Due to important refactoring needs and the Switzerland adoption of new international payment standard during 2013-2014. We have reorganised the swiss localization addons this way:
|
||||
**Translation contributors:** brain-tec AG, Agile Business Group
|
||||
|
||||
- **l10n_ch**: Multilang swiss STERCHI account chart and taxes (official addon)
|
||||
- **l10n_ch_base_bank**: Technical module that introduces a new and simplified version of bank type management
|
||||
- **l10n_ch_bank**: List of swiss banks
|
||||
- **l10n_ch_zip**: List of swiss postal zip
|
||||
- **l10n_ch_dta**: Support of dta payment protocol (will be deprecated end 2014)
|
||||
- **l10n_ch_payment_slip**: Support of ESR/BVR payment slip report and reconciliation. Report refactored with easy element positioning.
|
||||
- **l10n_ch_sepa**: Alpha implementation of PostFinance SEPA/PAIN support will be completed during 2013/2014
|
||||
The swiss localization addons are organized this way:
|
||||
|
||||
The modules will be soon available on OpenERP swiss localization on launchpad:
|
||||
https://launchpad.net/openerp-swiss-localization
|
||||
``l10n_ch``
|
||||
Multilang Swiss PME/KMU 2015 account chart and taxes (official addon)
|
||||
``l10n_ch_base_bank``
|
||||
Technical module that introduces a new and simplified version of bank
|
||||
type management
|
||||
``l10n_ch_bank``
|
||||
List of swiss banks
|
||||
``l10n_ch_zip``
|
||||
List of swiss postal zip
|
||||
``l10n_ch_dta``
|
||||
Support of the DTA payment protocol (will be deprecated by the end of 2014)
|
||||
``l10n_ch_payment_slip``
|
||||
Support of ESR/BVR payment slip report and reconciliation.
|
||||
|
||||
``l10n_ch`` is located in the core Odoo modules. The other modules are in:
|
||||
https://github.com/OCA/l10n-switzerland
|
||||
""",
|
||||
'version': '7.0',
|
||||
'version': '8.0',
|
||||
'author': 'Camptocamp',
|
||||
'category': 'Localization/Account Charts',
|
||||
'website': 'http://www.camptocamp.com',
|
||||
'depends': ['account', 'l10n_multilang'],
|
||||
'data': ['sterchi_chart/account.xml',
|
||||
'sterchi_chart/vat2011.xml',
|
||||
'sterchi_chart/fiscal_position.xml' ],
|
||||
'data': ['report/balance_sheet.xml',
|
||||
'report/profit_and_loss.xml',
|
||||
'chart/account.xml',
|
||||
'chart/vat2011.xml',
|
||||
'chart/fiscal_position.xml',
|
||||
|
||||
],
|
||||
'demo': [],
|
||||
'test': [],
|
||||
'auto_install': False,
|
||||
'installable': True,
|
||||
'images': ['images/config_chart_l10n_ch.jpeg','images/l10n_ch_chart.jpeg']
|
||||
}
|
||||
'images': ['images/config_chart_l10n_ch.jpeg', 'images/l10n_ch_chart.jpeg']
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -148,8 +148,8 @@
|
||||
<field name="ref_base_sign" eval="-1.0"/>
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="account_collected_id" ref="ch_1170"/>
|
||||
<field name="account_paid_id" ref="ch_1170"/>
|
||||
<field name="account_collected_id" ref="ch_coa_2200"/>
|
||||
<field name="account_paid_id" ref="ch_coa_2200"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_25_purchase">
|
||||
@@ -169,8 +169,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1170"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1170"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_25_invest">
|
||||
<field name="name">TVA 2.5% sur invest. et autres ch. (TR)</field>
|
||||
@@ -189,8 +189,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1171"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1171"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.template" id="vat_38">
|
||||
@@ -210,8 +210,8 @@
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="ch_1170"/>
|
||||
<field name="account_paid_id" ref="ch_1170"/>
|
||||
<field name="account_collected_id" ref="ch_coa_2200"/>
|
||||
<field name="account_paid_id" ref="ch_coa_2200"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_38_purchase">
|
||||
<field name="name">TVA 3.8% sur achat B&S (TS)</field>
|
||||
@@ -230,8 +230,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1170"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1170"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_38_invest">
|
||||
<field name="name">TVA 3.8% sur invest. et autres ch. (TS)</field>
|
||||
@@ -250,8 +250,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1171"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1171"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_80">
|
||||
<field name="name">TVA due a 8.0% (TN)</field>
|
||||
@@ -271,8 +271,8 @@
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="ch_1170"/>
|
||||
<field name="account_paid_id" ref="ch_1170"/>
|
||||
<field name="account_collected_id" ref="ch_coa_2200"/>
|
||||
<field name="account_paid_id" ref="ch_coa_2200"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_80_purchase">
|
||||
<field name="name">TVA 8.0% sur achat B&S (TN)</field>
|
||||
@@ -292,8 +292,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1170"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1170"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_80_invest">
|
||||
<field name="name">TVA 8.0% sur invest. et autres ch. (TN)</field>
|
||||
@@ -312,8 +312,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1171"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1171"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_XO">
|
||||
<field name="name">TVA due a 0% (Exportations)</field>
|
||||
@@ -330,8 +330,8 @@
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="ch_1170"/>
|
||||
<field name="account_paid_id" ref="ch_1170"/>
|
||||
<field name="account_collected_id" ref="ch_coa_2200"/>
|
||||
<field name="account_paid_id" ref="ch_coa_2200"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_O_exclude">
|
||||
<field name="name">TVA 0% exclue</field>
|
||||
@@ -348,8 +348,8 @@
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_2200"/>
|
||||
<field name="account_paid_id" ref="ch_coa_2200"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_O_import">
|
||||
<field name="name">TVA 0% Importations de biens et services</field>
|
||||
@@ -366,8 +366,8 @@
|
||||
<field name="ref_tax_sign" eval="1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1171"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1171"/>
|
||||
</record>
|
||||
<!--# 100% on import !! the tax percentage is 00-->
|
||||
<record model="account.tax.template" id="vat_100_import">
|
||||
@@ -383,8 +383,8 @@
|
||||
<field name="ref_tax_sign" eval="-1.0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="account_collected_id" ref="ch_1171"/>
|
||||
<field name="account_paid_id" ref="ch_1171"/>
|
||||
<field name="account_collected_id" ref="ch_coa_1171"/>
|
||||
<field name="account_paid_id" ref="ch_coa_1171"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
+996
-6123
File diff suppressed because it is too large
Load Diff
+998
-6123
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record id="financial_report_9" model="account.financial.report">
|
||||
<field name="name">BILAN</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_flat</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_10" model="account.financial.report">
|
||||
<field name="name">ACTIF</field>
|
||||
<field name="sequence">13</field>
|
||||
<field name="parent_id" ref="financial_report_9"/>
|
||||
<field name="style_overwrite" eval="2"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_flat</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_43" model="account.financial.report">
|
||||
<field name="name">ACTIF CIRCULANTS</field>
|
||||
<field name="sequence">14</field>
|
||||
<field name="parent_id" ref="financial_report_10"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_flat</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_11" model="account.financial.report">
|
||||
<field name="name">PASSIF</field>
|
||||
<field name="sequence">28</field>
|
||||
<field name="parent_id" ref="financial_report_9"/>
|
||||
<field name="style_overwrite" eval="2"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_flat</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_13" model="account.financial.report">
|
||||
<field name="name">Trésorerie</field>
|
||||
<field name="sequence">15</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_14" model="account.financial.report">
|
||||
<field name="name">Créances résultant de livraisons et prestations</field>
|
||||
<field name="sequence">17</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_15" model="account.financial.report">
|
||||
<field name="name">Autres créances à court terme</field>
|
||||
<field name="sequence">18</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_16" model="account.financial.report">
|
||||
<field name="name">Stocks et prestations non facturées</field>
|
||||
<field name="sequence">19</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_17" model="account.financial.report">
|
||||
<field name="name">Actifs de régularisation (transitoires)</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_18" model="account.financial.report">
|
||||
<field name="name">ACTIF IMMOBILISES</field>
|
||||
<field name="sequence">21</field>
|
||||
<field name="parent_id" ref="financial_report_10"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_with_hierarchy</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_19" model="account.financial.report">
|
||||
<field name="name">Immobilisations financières</field>
|
||||
<field name="sequence">22</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_20" model="account.financial.report">
|
||||
<field name="name">Participations</field>
|
||||
<field name="sequence">23</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_21" model="account.financial.report">
|
||||
<field name="name">Immobilisations corporelles meubles</field>
|
||||
<field name="sequence">24</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_22" model="account.financial.report">
|
||||
<field name="name">Immobilisation incorporelles</field>
|
||||
<field name="sequence">26</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_23" model="account.financial.report">
|
||||
<field name="name">Capital non versé : capital social, capital de fondation</field>
|
||||
<field name="sequence">27</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_24" model="account.financial.report">
|
||||
<field name="name">DETTES A COURT TERME</field>
|
||||
<field name="sequence">29</field>
|
||||
<field name="parent_id" ref="financial_report_11"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_25" model="account.financial.report">
|
||||
<field name="name">Dettes à court terme résultant d’achats et de prestations de services</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="parent_id" ref="financial_report_24"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_26" model="account.financial.report">
|
||||
<field name="name">Dettes à court terme rémunérés</field>
|
||||
<field name="sequence">31</field>
|
||||
<field name="parent_id" ref="financial_report_24"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_27" model="account.financial.report">
|
||||
<field name="name">Autres dettes à court terme</field>
|
||||
<field name="sequence">32</field>
|
||||
<field name="parent_id" ref="financial_report_24"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_29" model="account.financial.report">
|
||||
<field name="name">Passifs de régularisation (transitoires) et provisions à court terme</field>
|
||||
<field name="sequence">33</field>
|
||||
<field name="parent_id" ref="financial_report_24"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_30" model="account.financial.report">
|
||||
<field name="name">DETTES A LONG TERME</field>
|
||||
<field name="sequence">34</field>
|
||||
<field name="parent_id" ref="financial_report_11"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_31" model="account.financial.report">
|
||||
<field name="name">Dettes à long terme rémunérées</field>
|
||||
<field name="sequence">35</field>
|
||||
<field name="parent_id" ref="financial_report_30"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_33" model="account.financial.report">
|
||||
<field name="name">Provisions à long termes et provisions légales</field>
|
||||
<field name="sequence">37</field>
|
||||
<field name="parent_id" ref="financial_report_30"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_36" model="account.financial.report">
|
||||
<field name="name">CAPITAUX PROPRES</field>
|
||||
<field name="sequence">38</field>
|
||||
<field name="parent_id" ref="financial_report_11"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_37" model="account.financial.report">
|
||||
<field name="name">Autres dettes à long terme</field>
|
||||
<field name="sequence">36</field>
|
||||
<field name="parent_id" ref="financial_report_30"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_38" model="account.financial.report">
|
||||
<field name="name">Capital social</field>
|
||||
<field name="sequence">39</field>
|
||||
<field name="parent_id" ref="financial_report_36"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_39" model="account.financial.report">
|
||||
<field name="name">Réserves / bénéfices et pertes reportés</field>
|
||||
<field name="sequence">40</field>
|
||||
<field name="parent_id" ref="financial_report_36"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,218 @@
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record id="financial_report_44" model="account.financial.report">
|
||||
<field name="name">COMPTE DE RESULTAT</field>
|
||||
<field name="sequence">44</field>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">detail_flat</field>
|
||||
<field name="type">sum</field>
|
||||
</record>
|
||||
<record id="financial_report_45" model="account.financial.report">
|
||||
<field name="name">Produits net des ventes de biens et de prestations de services</field>
|
||||
<field name="sequence">48</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_46" model="account.financial.report">
|
||||
<field name="name">Bénéfice ou perte de l'exercice</field>
|
||||
<field name="sequence">41</field>
|
||||
<field name="parent_id" ref="financial_report_36"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_47" model="account.financial.report">
|
||||
<field name="name">Actifs à court terme cotés en bourse</field>
|
||||
<field name="sequence">16</field>
|
||||
<field name="parent_id" ref="financial_report_43"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_48" model="account.financial.report">
|
||||
<field name="name">Charges de matériel</field>
|
||||
<field name="sequence">51</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_49" model="account.financial.report">
|
||||
<field name="name">Charges de personnel</field>
|
||||
<field name="sequence">53</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_50" model="account.financial.report">
|
||||
<field name="name">Autres charges d‘exploitation</field>
|
||||
<field name="sequence">55</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_51" model="account.financial.report">
|
||||
<field name="name">Amortissement et corrections de valeur des postes sur immobilisations corporelles</field>
|
||||
<field name="sequence">57</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_52" model="account.financial.report">
|
||||
<field name="name">Produits financiers</field>
|
||||
<field name="sequence">59</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_53" model="account.financial.report">
|
||||
<field name="name">Résultat hors exploitation</field>
|
||||
<field name="sequence">63</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_54" model="account.financial.report">
|
||||
<field name="name">Résultat exceptionnel</field>
|
||||
<field name="sequence">64</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_55" model="account.financial.report">
|
||||
<field name="name">Impôts directs</field>
|
||||
<field name="sequence">66</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_57" model="account.financial.report">
|
||||
<field name="name">Variation des stocks et de produits finis et semi-finis et variation des prestations de services non facturés</field>
|
||||
<field name="sequence">49</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_58" model="account.financial.report">
|
||||
<field name="name">= CHIFFRE D’AFFAIRES SUR VENTES ET PRESTATIONS DE SERVICES</field>
|
||||
<field name="sequence">50</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_59" model="account.financial.report">
|
||||
<field name="name">= RESULTAT BRUT APRES CHARGES DE MATIERES ET MARCHANDISES</field>
|
||||
<field name="sequence">52</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_60" model="account.financial.report">
|
||||
<field name="name">= RESULTAT APRES CHARGES DE PERSONNEL</field>
|
||||
<field name="sequence">54</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_61" model="account.financial.report">
|
||||
<field name="name">= EBITDA</field>
|
||||
<field name="sequence">56</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_62" model="account.financial.report">
|
||||
<field name="name">= EBIT</field>
|
||||
<field name="sequence">58</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_63" model="account.financial.report">
|
||||
<field name="name">Charges financières</field>
|
||||
<field name="sequence">60</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_65" model="account.financial.report">
|
||||
<field name="name">= RESULTAT D'EXPLOITATION AVANT IMPOTS (EBT)</field>
|
||||
<field name="sequence">61</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_66" model="account.financial.report">
|
||||
<field name="name">Résultat des activités annexes des exploitations</field>
|
||||
<field name="sequence">62</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_67" model="account.financial.report">
|
||||
<field name="name">= RESULTAT AVANT IMPOTS</field>
|
||||
<field name="sequence">65</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="3"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_68" model="account.financial.report">
|
||||
<field name="name">= BENEFICE OU PERTE DE L'EXERCICE</field>
|
||||
<field name="sequence">67</field>
|
||||
<field name="parent_id" ref="financial_report_44"/>
|
||||
<field name="style_overwrite" eval="2"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
<record id="financial_report_69" model="account.financial.report">
|
||||
<field name="name">Immobilisations corporelles immeubles</field>
|
||||
<field name="sequence">25</field>
|
||||
<field name="parent_id" ref="financial_report_18"/>
|
||||
<field name="style_overwrite" eval="4"/>
|
||||
<field name="sign" eval="1"/>
|
||||
<field name="display_detail">no_detail</field>
|
||||
<field name="type">accounts</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -155,7 +155,7 @@ class mail_mail(osv.Model):
|
||||
if context is None:
|
||||
context = {}
|
||||
if partner and partner.user_ids:
|
||||
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
|
||||
base_url = self.pool.get('ir.config_parameter').get_param(cr, SUPERUSER_ID, 'web.base.url')
|
||||
mail_model = mail.model or 'mail.thread'
|
||||
url = urljoin(base_url, self.pool[mail_model]._get_access_link(cr, uid, mail, partner, context=context))
|
||||
return "<span class='oe_mail_footer_access'><small>%(access_msg)s <a style='color:inherit' href='%(portal_link)s'>%(portal_msg)s</a></small></span>" % {
|
||||
|
||||
@@ -652,8 +652,8 @@ openerp.mail = function (session) {
|
||||
if (self.flag_post) {
|
||||
return;
|
||||
}
|
||||
self.flag_post = true;
|
||||
if (this.do_check_attachment_upload() && (this.attachment_ids.length || this.$('textarea').val().match(/\S+/))) {
|
||||
self.flag_post = true;
|
||||
if (this.is_log) {
|
||||
this.do_send_message_post([], this.is_log);
|
||||
}
|
||||
@@ -880,7 +880,11 @@ openerp.mail = function (session) {
|
||||
self.parent_thread.message_fetch(this.domain, this.context, false, function (arg, data) {
|
||||
self.id = false;
|
||||
// insert the message on dom after this message
|
||||
self.parent_thread.switch_new_message(data, self.$el);
|
||||
var element = self.$el;
|
||||
if (self.thread_level === 0){
|
||||
element = element.parent();
|
||||
}
|
||||
self.parent_thread.switch_new_message(data, element);
|
||||
self.animated_destroy(200);
|
||||
});
|
||||
|
||||
@@ -1943,7 +1947,7 @@ openerp.mail = function (session) {
|
||||
'show_compact_message': this.action.params.view_mailbox ? false : 1,
|
||||
'view_inbox': false,
|
||||
'emails_from_on_composer': false,
|
||||
'fetch_limit': 1000 // allow inbox to load all children messages
|
||||
'fetch_limit': 30 // allow inbox to load all children messages
|
||||
}, this.action.params);
|
||||
},
|
||||
|
||||
|
||||
@@ -20,10 +20,8 @@
|
||||
self.$target.find('a.js_subscribe_btn')
|
||||
.attr("disabled", data.is_subscriber && data.email.length ? "disabled" : false);
|
||||
self.$target.removeClass("hidden");
|
||||
if (data.is_subscriber) {
|
||||
self.$target.find('.js_subscribe_btn').addClass('hidden');
|
||||
self.$target.find('.js_subscribed_btn').removeClass('hidden');
|
||||
}
|
||||
self.$target.find('.js_subscribe_btn').toggleClass('hidden', !!data.is_subscriber);
|
||||
self.$target.find('.js_subscribed_btn').toggleClass('hidden', !data.is_subscriber);
|
||||
});
|
||||
|
||||
// not if editable mode to allow designer to edit alert field
|
||||
|
||||
+9
-2
@@ -737,9 +737,13 @@ class mrp_production(osv.osv):
|
||||
if context is None:
|
||||
context = {}
|
||||
move_obj = self.pool.get('stock.move')
|
||||
proc_obj = self.pool.get('procurement.order')
|
||||
for production in self.browse(cr, uid, ids, context=context):
|
||||
if production.move_created_ids:
|
||||
move_obj.action_cancel(cr, uid, [x.id for x in production.move_created_ids])
|
||||
procs = proc_obj.search(cr, uid, [('move_dest_id', 'in', [x.id for x in production.move_lines])], context=context)
|
||||
if procs:
|
||||
proc_obj.cancel(cr, uid, procs, context=context)
|
||||
move_obj.action_cancel(cr, uid, [x.id for x in production.move_lines])
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
# Put related procurements in exception
|
||||
@@ -1057,7 +1061,8 @@ class mrp_production(osv.osv):
|
||||
source_location_id = production.product_id.property_stock_production.id
|
||||
destination_location_id = production.location_dest_id.id
|
||||
procs = proc_obj.search(cr, uid, [('production_id', '=', production.id)], context=context)
|
||||
procurement_id = procs and procs[0] or False
|
||||
procurement = procs and\
|
||||
proc_obj.browse(cr, uid, procs[0], context=context) or False
|
||||
data = {
|
||||
'name': production.name,
|
||||
'date': production.date_planned,
|
||||
@@ -1069,10 +1074,11 @@ class mrp_production(osv.osv):
|
||||
'location_id': source_location_id,
|
||||
'location_dest_id': destination_location_id,
|
||||
'move_dest_id': production.move_prod_id.id,
|
||||
'procurement_id': procurement_id,
|
||||
'procurement_id': procurement and procurement.id,
|
||||
'company_id': production.company_id.id,
|
||||
'production_id': production.id,
|
||||
'origin': production.name,
|
||||
'group_id': procurement and procurement.group_id.id,
|
||||
}
|
||||
move_id = stock_move.create(cr, uid, data, context=context)
|
||||
#a phantom bom cannot be used in mrp order so it's ok to assume the list returned by action_confirm
|
||||
@@ -1157,6 +1163,7 @@ class mrp_production(osv.osv):
|
||||
'price_unit': product.standard_price,
|
||||
'origin': production.name,
|
||||
'warehouse_id': loc_obj.get_warehouse(cr, uid, production.location_src_id, context=context),
|
||||
'group_id': production.move_prod_id.group_id.id,
|
||||
}, context=context)
|
||||
|
||||
if prev_move:
|
||||
|
||||
+39
-31
@@ -23,6 +23,7 @@ from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
class procurement_rule(osv.osv):
|
||||
@@ -69,47 +70,54 @@ class procurement_order(osv.osv):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _get_date_planned(self, cr, uid, procurement, context=None):
|
||||
format_date_planned = datetime.strptime(procurement.date_planned,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
date_planned = format_date_planned - relativedelta(days=procurement.product_id.produce_delay or 0.0)
|
||||
date_planned = date_planned - relativedelta(days=procurement.company_id.manufacturing_lead)
|
||||
return date_planned
|
||||
|
||||
def _prepare_mo_vals(self, cr, uid, procurement, context=None):
|
||||
res_id = procurement.move_dest_id and procurement.move_dest_id.id or False
|
||||
newdate = self._get_date_planned(cr, uid, procurement, context=context)
|
||||
bom_obj = self.pool.get('mrp.bom')
|
||||
if procurement.bom_id:
|
||||
bom_id = procurement.bom_id.id
|
||||
routing_id = procurement.bom_id.routing_id.id
|
||||
else:
|
||||
properties = [x.id for x in procurement.property_ids]
|
||||
bom_id = bom_obj._bom_find(cr, uid, product_id=procurement.product_id.id,
|
||||
properties=properties, context=context)
|
||||
bom = bom_obj.browse(cr, uid, bom_id, context=context)
|
||||
routing_id = bom.routing_id.id
|
||||
return {
|
||||
'origin': procurement.origin,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
|
||||
'product_uos': procurement.product_uos and procurement.product_uos.id or False,
|
||||
'location_src_id': procurement.location_id.id,
|
||||
'location_dest_id': procurement.location_id.id,
|
||||
'bom_id': bom_id,
|
||||
'routing_id': routing_id,
|
||||
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'move_prod_id': res_id,
|
||||
'company_id': procurement.company_id.id,
|
||||
}
|
||||
|
||||
def make_mo(self, cr, uid, ids, context=None):
|
||||
""" Make Manufacturing(production) order from procurement
|
||||
@return: New created Production Orders procurement wise
|
||||
"""
|
||||
res = {}
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
|
||||
production_obj = self.pool.get('mrp.production')
|
||||
bom_obj = self.pool.get('mrp.bom')
|
||||
procurement_obj = self.pool.get('procurement.order')
|
||||
for procurement in procurement_obj.browse(cr, uid, ids, context=context):
|
||||
if self.check_bom_exists(cr, uid, [procurement.id], context=context):
|
||||
if procurement.bom_id:
|
||||
bom_id = procurement.bom_id.id
|
||||
routing_id = procurement.bom_id.routing_id.id
|
||||
else:
|
||||
properties = [x.id for x in procurement.property_ids]
|
||||
bom_id = bom_obj._bom_find(cr, uid, product_id=procurement.product_id.id,
|
||||
properties=properties, context=context)
|
||||
bom = bom_obj.browse(cr, uid, bom_id, context=context)
|
||||
routing_id = bom.routing_id.id
|
||||
|
||||
res_id = procurement.move_dest_id and procurement.move_dest_id.id or False
|
||||
newdate = datetime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - relativedelta(days=procurement.product_id.produce_delay or 0.0)
|
||||
newdate = newdate - relativedelta(days=company.manufacturing_lead)
|
||||
#create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example)
|
||||
produce_id = production_obj.create(cr, SUPERUSER_ID, {
|
||||
'origin': procurement.origin,
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_qty': procurement.product_qty,
|
||||
'product_uom': procurement.product_uom.id,
|
||||
'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
|
||||
'product_uos': procurement.product_uos and procurement.product_uos.id or False,
|
||||
'location_src_id': procurement.location_id.id,
|
||||
'location_dest_id': procurement.location_id.id,
|
||||
'bom_id': bom_id,
|
||||
'routing_id': routing_id,
|
||||
'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'move_prod_id': res_id,
|
||||
'company_id': procurement.company_id.id,
|
||||
})
|
||||
|
||||
vals = self._prepare_mo_vals(cr, uid, procurement, context=context)
|
||||
produce_id = production_obj.create(cr, SUPERUSER_ID, vals, context=context)
|
||||
res[procurement.id] = produce_id
|
||||
self.write(cr, uid, [procurement.id], {'production_id': produce_id})
|
||||
self.production_order_create_note(cr, uid, procurement, context=context)
|
||||
|
||||
+3
-1
@@ -37,7 +37,9 @@ class pad_common(osv.osv_memory):
|
||||
s = string.ascii_uppercase + string.digits
|
||||
salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(10)])
|
||||
#path
|
||||
path = '%s-%s-%s' % (cr.dbname.replace('_','-'), self._name, salt)
|
||||
# etherpad hardcodes pad id length limit to 50
|
||||
path = '-%s-%s' % (self._name, salt)
|
||||
path = '%s%s' % (cr.dbname.replace('_','-')[0:50 - len(path)], path)
|
||||
# contruct the url
|
||||
url = '%s/p/%s' % (pad["server"], path)
|
||||
|
||||
|
||||
@@ -57,6 +57,8 @@ class AcquirerBuckaroo(osv.Model):
|
||||
return values[key]
|
||||
return ''
|
||||
|
||||
values = dict(values or {})
|
||||
|
||||
if inout == 'out':
|
||||
if 'BRQ_SIGNATURE' in values:
|
||||
del values['BRQ_SIGNATURE']
|
||||
@@ -81,12 +83,12 @@ class AcquirerBuckaroo(osv.Model):
|
||||
'Brq_amount': tx_values['amount'],
|
||||
'Brq_currency': tx_values['currency'] and tx_values['currency'].name or '',
|
||||
'Brq_invoicenumber': tx_values['reference'],
|
||||
'brq_test' : True,
|
||||
'brq_test': False if acquirer.environment == 'prod' else True,
|
||||
'Brq_return': '%s' % urlparse.urljoin(base_url, BuckarooController._return_url),
|
||||
'Brq_returncancel': '%s' % urlparse.urljoin(base_url, BuckarooController._cancel_url),
|
||||
'Brq_returnerror': '%s' % urlparse.urljoin(base_url, BuckarooController._exception_url),
|
||||
'Brq_returnreject': '%s' % urlparse.urljoin(base_url, BuckarooController._reject_url),
|
||||
'Brq_culture': 'en-US',
|
||||
'Brq_culture': (partner_values.get('lang') or 'en_US').replace('_', '-'),
|
||||
})
|
||||
if buckaroo_tx_values.get('return_url'):
|
||||
buckaroo_tx_values['add_returndata'] = {'return_url': '%s' % buckaroo_tx_values.pop('return_url')}
|
||||
|
||||
@@ -224,10 +224,10 @@ class PaymentTxOgone(osv.Model):
|
||||
def _ogone_form_get_invalid_parameters(self, cr, uid, tx, data, context=None):
|
||||
invalid_parameters = []
|
||||
|
||||
# TODO: txn_id: shoudl be false at draft, set afterwards, and verified with txn details
|
||||
# TODO: txn_id: should be false at draft, set afterwards, and verified with txn details
|
||||
if tx.acquirer_reference and data.get('PAYID') != tx.acquirer_reference:
|
||||
invalid_parameters.append(('PAYID', data.get('PAYID'), tx.acquirer_reference))
|
||||
# check what is buyed
|
||||
# check what is bought
|
||||
if float_compare(float(data.get('amount', '0.0')), tx.amount, 2) != 0:
|
||||
invalid_parameters.append(('amount', data.get('amount'), '%.2f' % tx.amount))
|
||||
if data.get('currency') != tx.currency_id.name:
|
||||
|
||||
@@ -871,7 +871,15 @@ class pos_order(osv.osv):
|
||||
'name': order.name + ': ' + (data.get('payment_name', '') or ''),
|
||||
'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False,
|
||||
}
|
||||
account_def = property_obj.get(cr, uid, 'property_account_receivable', 'res.partner', context=context)
|
||||
|
||||
journal_id = data.get('journal', False)
|
||||
statement_id = data.get('statement_id', False)
|
||||
assert journal_id or statement_id, "No statement_id or journal_id passed to the method!"
|
||||
|
||||
journal = self.pool['account.journal'].browse(cr, uid, journal_id, context=context)
|
||||
# use the company of the journal and not of the current user
|
||||
company_cxt = dict(context, force_company=journal.company_id.id)
|
||||
account_def = property_obj.get(cr, uid, 'property_account_receivable', 'res.partner', context=company_cxt)
|
||||
args['account_id'] = (order.partner_id and order.partner_id.property_account_receivable \
|
||||
and order.partner_id.property_account_receivable.id) or (account_def and account_def.id) or False
|
||||
|
||||
@@ -884,10 +892,6 @@ class pos_order(osv.osv):
|
||||
|
||||
context.pop('pos_session_id', False)
|
||||
|
||||
journal_id = data.get('journal', False)
|
||||
statement_id = data.get('statement_id', False)
|
||||
assert journal_id or statement_id, "No statement_id or journal_id passed to the method!"
|
||||
|
||||
for statement in order.session_id.statement_ids:
|
||||
if statement.id == statement_id:
|
||||
journal_id = statement.journal_id.id
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<field name="sequence_id" ref="seq_picking_type_posout"/>
|
||||
<field name="default_location_src_id" ref="stock.stock_location_stock"/>
|
||||
<field name="default_location_dest_id" ref="stock.stock_location_customers"/>
|
||||
<field name="warehouse_id" eval="False"/>
|
||||
<field name="code">outgoing</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -716,7 +716,7 @@
|
||||
</group>
|
||||
<group string="Receipt" >
|
||||
<field name="receipt_header" string="Header" placeholder="A custom receipt header message"/>
|
||||
<field name="receipt_footer" string="Footer" placeholder="A custom receipt header footage"/>
|
||||
<field name="receipt_footer" string="Footer" placeholder="A custom receipt footer message"/>
|
||||
</group>
|
||||
</sheet>
|
||||
|
||||
|
||||
@@ -109,7 +109,8 @@ class pos_details(report_sxw.rml_parse):
|
||||
statement_line_obj = self.pool.get("account.bank.statement.line")
|
||||
pos_order_obj = self.pool.get("pos.order")
|
||||
user_ids = form['user_ids'] or self._get_all_users()
|
||||
pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids)])
|
||||
company_id = self.pool['res.users'].browse(self.cr, self.uid, self.uid).company_id.id
|
||||
pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
|
||||
data={}
|
||||
if pos_ids:
|
||||
st_line_ids = statement_line_obj.search(self.cr, self.uid, [('pos_statement_id', 'in', pos_ids)])
|
||||
@@ -157,7 +158,8 @@ class pos_details(report_sxw.rml_parse):
|
||||
account_tax_obj = self.pool.get('account.tax')
|
||||
user_ids = form['user_ids'] or self._get_all_users()
|
||||
pos_order_obj = self.pool.get('pos.order')
|
||||
pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids)])
|
||||
company_id = self.pool['res.users'].browse(self.cr, self.uid, self.uid).company_id.id
|
||||
pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids), ('company_id', '=', company_id)])
|
||||
for order in pos_order_obj.browse(self.cr, self.uid, pos_ids):
|
||||
for line in order.lines:
|
||||
line_taxes = account_tax_obj.compute_all(self.cr, self.uid, line.product_id.taxes_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
|
||||
|
||||
@@ -153,24 +153,25 @@ openerp.point_of_sale.load_db = function load_db(instance, module){
|
||||
this.cache[store] = data;
|
||||
},
|
||||
_product_search_string: function(product){
|
||||
var str = '' + product.id + ':' + product.display_name;
|
||||
var str = product.display_name;
|
||||
if (product.barcode) {
|
||||
str += '|' + product.barcode;
|
||||
}
|
||||
if (product.default_code) {
|
||||
str += '|' + product.default_code.replace(':','');
|
||||
str += '|' + product.default_code;
|
||||
}
|
||||
if (product.description) {
|
||||
str += '|' + product.description.replace(':','');
|
||||
str += '|' + product.description;
|
||||
}
|
||||
if (product.description_sale) {
|
||||
str += '|' + product.description_sale.replace(':','');
|
||||
str += '|' + product.description_sale;
|
||||
}
|
||||
var packagings = this.packagings_by_product_tmpl_id[product.product_tmpl_id] || [];
|
||||
for (var i = 0; i < packagings.length; i++) {
|
||||
str += '|' + packagings[i].barcode;
|
||||
}
|
||||
return str + '\n';
|
||||
str = product.id + ':' + str.replace(':','') + '\n';
|
||||
return str;
|
||||
},
|
||||
add_products: function(products){
|
||||
var stored_categories = this.product_by_category_id;
|
||||
@@ -227,7 +228,7 @@ openerp.point_of_sale.load_db = function load_db(instance, module){
|
||||
}
|
||||
},
|
||||
_partner_search_string: function(partner){
|
||||
var str = '' + partner.id + ':' + partner.name;
|
||||
var str = partner.name;
|
||||
if(partner.barcode){
|
||||
str += '|' + partner.barcode;
|
||||
}
|
||||
@@ -243,7 +244,8 @@ openerp.point_of_sale.load_db = function load_db(instance, module){
|
||||
if(partner.email){
|
||||
str += '|' + partner.email;
|
||||
}
|
||||
return str + '\n';
|
||||
str = '' + partner.id + ':' + str.replace(':','') + '\n';
|
||||
return str;
|
||||
},
|
||||
add_partners: function(partners){
|
||||
var updated_count = 0;
|
||||
|
||||
@@ -183,7 +183,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
},
|
||||
},{
|
||||
model: 'account.tax',
|
||||
fields: ['name','amount', 'price_include', 'type'],
|
||||
fields: ['name','amount', 'price_include', 'include_base_amount', 'type'],
|
||||
domain: null,
|
||||
loaded: function(self,taxes){
|
||||
self.taxes = taxes;
|
||||
@@ -1036,7 +1036,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
},
|
||||
get_base_price: function(){
|
||||
var rounding = this.pos.currency.rounding;
|
||||
return round_pr(round_pr(this.get_unit_price() * this.get_quantity(),rounding) * (1- this.get_discount()/100.0),rounding);
|
||||
return round_pr(this.get_unit_price() * this.get_quantity() * (1 - this.get_discount()/100), rounding);
|
||||
},
|
||||
get_display_price: function(){
|
||||
return this.get_base_price();
|
||||
@@ -1055,6 +1055,22 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
get_tax: function(){
|
||||
return this.get_all_prices().tax;
|
||||
},
|
||||
get_applicable_taxes: function(){
|
||||
// Shenaningans because we need
|
||||
// to keep the taxes ordering.
|
||||
var ptaxes_ids = this.get_product().taxes_id;
|
||||
var ptaxes_set = {};
|
||||
for (var i = 0; i < ptaxes_ids.length; i++) {
|
||||
ptaxes_set[ptaxes_ids[i]] = true;
|
||||
}
|
||||
var taxes = [];
|
||||
for (var i = 0; i < this.pos.taxes.length; i++) {
|
||||
if (ptaxes_set[this.pos.taxes[i].id]) {
|
||||
taxes.push(this.pos.taxes[i]);
|
||||
}
|
||||
}
|
||||
return taxes;
|
||||
},
|
||||
get_tax_details: function(){
|
||||
return this.get_all_prices().taxDetails;
|
||||
},
|
||||
@@ -1074,12 +1090,10 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
var totalNoTax = base;
|
||||
|
||||
var product = this.get_product();
|
||||
var taxes_ids = product.taxes_id;
|
||||
var taxes = self.pos.taxes;
|
||||
var taxes = this.get_applicable_taxes();
|
||||
var taxtotal = 0;
|
||||
var taxdetail = {};
|
||||
_.each(taxes_ids, function(el) {
|
||||
var tax = _.detect(taxes, function(t) {return t.id === el;});
|
||||
_.each(taxes, function(tax) {
|
||||
if (tax.price_include) {
|
||||
var tmp;
|
||||
if (tax.type === "percent") {
|
||||
@@ -1102,7 +1116,13 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
} else {
|
||||
throw "This type of tax is not supported by the point of sale: " + tax.type;
|
||||
}
|
||||
|
||||
tmp = round_pr(tmp,currency_rounding);
|
||||
|
||||
if (tax.include_base_amount) {
|
||||
base += tmp;
|
||||
}
|
||||
|
||||
taxtotal += tmp;
|
||||
totalTax += tmp;
|
||||
taxdetail[tax.id] = tmp;
|
||||
@@ -1157,6 +1177,10 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
this.trigger('change',this);
|
||||
}
|
||||
},
|
||||
// returns the payment type: 'cash' | 'bank'
|
||||
get_type: function(){
|
||||
return this.cashregister.journal.type
|
||||
},
|
||||
// returns the associated cashregister
|
||||
//exports as JSON for server communication
|
||||
export_as_JSON: function(){
|
||||
@@ -1565,11 +1589,6 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
get_tax_details: function(){
|
||||
var details = {};
|
||||
var fulldetails = [];
|
||||
var taxes_by_id = {};
|
||||
|
||||
for(var i = 0; i < this.pos.taxes.length; i++){
|
||||
taxes_by_id[this.pos.taxes[i].id] = this.pos.taxes[i];
|
||||
}
|
||||
|
||||
this.orderlines.each(function(line){
|
||||
var ldetails = line.get_tax_details();
|
||||
@@ -1582,7 +1601,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
|
||||
|
||||
for(var id in details){
|
||||
if(details.hasOwnProperty(id)){
|
||||
fulldetails.push({amount: details[id], tax: taxes_by_id[id], name: taxes_by_id[id].name});
|
||||
fulldetails.push({amount: details[id], tax: this.pos.taxes_by_id[id], name: this.pos.taxes_by_id[id].name});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1641,6 +1641,17 @@ openerp.point_of_sale.load_screens = function load_screens(instance, module){ //
|
||||
return;
|
||||
}
|
||||
|
||||
var plines = currentOrder.get('paymentLines').models;
|
||||
for (var i = 0; i < plines.length; i++) {
|
||||
if (plines[i].get_type() === 'bank' && plines[i].get_amount() < 0) {
|
||||
this.pos_widget.screen_selector.show_popup('error',{
|
||||
'message': _t('Negative Bank Payment'),
|
||||
'comment': _t('You cannot have a negative amount in a Bank payment. Use a cash payment method to return money to the customer.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!order.is_paid() || this.invoicing) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="oe_portal_project_issue">
|
||||
<field name="priority"/>
|
||||
<field name="user_email"/>
|
||||
<field name="user_id"/>
|
||||
<field name="date_deadline"/>
|
||||
|
||||
+45
-33
@@ -247,19 +247,27 @@ class product_pricelist(osv.osv):
|
||||
|
||||
results = {}
|
||||
for product, qty, partner in products_by_qty_by_partner:
|
||||
uom_price_already_computed = False
|
||||
results[product.id] = 0.0
|
||||
price = False
|
||||
rule_id = False
|
||||
price = False
|
||||
|
||||
# Final unit price is computed according to `qty` in the `qty_uom_id` UoM.
|
||||
# An intermediary unit price may be computed according to a different UoM, in
|
||||
# which case the price_uom_id contains that UoM.
|
||||
# The final price will be converted to match `qty_uom_id`.
|
||||
qty_uom_id = context.get('uom') or product.uom_id.id
|
||||
price_uom_id = product.uom_id.id
|
||||
qty_in_product_uom = qty
|
||||
if qty_uom_id != product.uom_id.id:
|
||||
try:
|
||||
qty_in_product_uom = product_uom_obj._compute_qty(
|
||||
cr, uid, context['uom'], qty, product.uom_id.id or product.uos_id.id)
|
||||
except except_orm:
|
||||
# Ignored - incompatible UoM in context, use default product UoM
|
||||
pass
|
||||
|
||||
for rule in items:
|
||||
if 'uom' in context and product.uom_id and context['uom'] != product.uom_id.id:
|
||||
try:
|
||||
qty_in_product_uom = product_uom_obj._compute_qty(cr, uid, context['uom'], qty, product.uom_id.id, dict(context.items() + [('raise-exception', False)]))
|
||||
except except_orm:
|
||||
qty_in_product_uom = qty
|
||||
else:
|
||||
qty_in_product_uom = qty
|
||||
if rule.min_quantity and qty_in_product_uom<rule.min_quantity:
|
||||
if rule.min_quantity and qty_in_product_uom < rule.min_quantity:
|
||||
continue
|
||||
if is_product_template:
|
||||
if rule.product_tmpl_id and product.id != rule.product_tmpl_id.id:
|
||||
@@ -287,7 +295,7 @@ class product_pricelist(osv.osv):
|
||||
rule.base_pricelist_id, [(product,
|
||||
qty, False)], context=context)[product.id]
|
||||
ptype_src = rule.base_pricelist_id.currency_id.id
|
||||
uom_price_already_computed = True
|
||||
price_uom_id = qty_uom_id
|
||||
price = currency_obj.compute(cr, uid,
|
||||
ptype_src, pricelist.currency_id.id,
|
||||
price_tmp, round=False,
|
||||
@@ -302,12 +310,10 @@ class product_pricelist(osv.osv):
|
||||
seller = product.seller_ids[0]
|
||||
if seller:
|
||||
qty_in_seller_uom = qty
|
||||
from_uom = context.get('uom') or product.uom_id.id
|
||||
seller_uom = seller.product_uom and seller.product_uom.id or False
|
||||
if seller_uom and from_uom and from_uom != seller_uom:
|
||||
qty_in_seller_uom = product_uom_obj._compute_qty(cr, uid, from_uom, qty, to_uom_id=seller_uom)
|
||||
else:
|
||||
uom_price_already_computed = True
|
||||
seller_uom = seller.product_uom.id
|
||||
if qty_uom_id != seller_uom:
|
||||
qty_in_seller_uom = product_uom_obj._compute_qty(cr, uid, qty_uom_id, qty, to_uom_id=seller_uom)
|
||||
price_uom_id = seller_uom
|
||||
for line in seller.pricelist_ids:
|
||||
if line.min_quantity <= qty_in_seller_uom:
|
||||
price = line.price
|
||||
@@ -317,34 +323,40 @@ class product_pricelist(osv.osv):
|
||||
price_types[rule.base] = price_type_obj.browse(cr, uid, int(rule.base))
|
||||
price_type = price_types[rule.base]
|
||||
|
||||
uom_price_already_computed = True
|
||||
price = currency_obj.compute(cr, uid,
|
||||
# price_get returns the price in the context UoM, i.e. qty_uom_id
|
||||
price_uom_id = qty_uom_id
|
||||
price = currency_obj.compute(
|
||||
cr, uid,
|
||||
price_type.currency_id.id, pricelist.currency_id.id,
|
||||
product_obj._price_get(cr, uid, [product],
|
||||
price_type.field, context=context)[product.id], round=False, context=context)
|
||||
product_obj._price_get(cr, uid, [product], price_type.field, context=context)[product.id],
|
||||
round=False, context=context)
|
||||
|
||||
if price is not False:
|
||||
price_limit = price
|
||||
price = price * (1.0+(rule.price_discount or 0.0))
|
||||
if rule.price_round:
|
||||
price = tools.float_round(price, precision_rounding=rule.price_round)
|
||||
if context.get('uom'):
|
||||
# compute price_surcharge based on reference uom
|
||||
factor = product_uom_obj.browse(cr, uid, context.get('uom'), context=context).factor
|
||||
else:
|
||||
factor = 1.0
|
||||
price += (rule.price_surcharge or 0.0) / factor
|
||||
|
||||
convert_to_price_uom = (lambda price: product_uom_obj._compute_price(
|
||||
cr, uid, product.uom_id.id,
|
||||
price, price_uom_id))
|
||||
if rule.price_surcharge:
|
||||
price_surcharge = convert_to_price_uom(rule.price_surcharge)
|
||||
price += price_surcharge
|
||||
|
||||
if rule.price_min_margin:
|
||||
price = max(price, price_limit+rule.price_min_margin)
|
||||
price_min_margin = convert_to_price_uom(rule.price_min_margin)
|
||||
price = max(price, price_limit + price_min_margin)
|
||||
|
||||
if rule.price_max_margin:
|
||||
price = min(price, price_limit+rule.price_max_margin)
|
||||
price_max_margin = convert_to_price_uom(rule.price_max_margin)
|
||||
price = min(price, price_limit + price_max_margin)
|
||||
|
||||
rule_id = rule.id
|
||||
break
|
||||
|
||||
if price:
|
||||
if 'uom' in context and not uom_price_already_computed:
|
||||
uom = product.uos_id or product.uom_id
|
||||
price = product_uom_obj._compute_price(cr, uid, uom.id, price, context['uom'])
|
||||
# Final price conversion to target UoM
|
||||
price = product_uom_obj._compute_price(cr, uid, price_uom_id, price, qty_uom_id)
|
||||
|
||||
results[product.id] = (price, rule_id)
|
||||
return results
|
||||
|
||||
@@ -177,7 +177,8 @@ class product_uom(osv.osv):
|
||||
return amount
|
||||
|
||||
def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
|
||||
if not from_uom_id or not price or not to_uom_id:
|
||||
if (not from_uom_id or not price or not to_uom_id
|
||||
or (to_uom_id == from_uom_id)):
|
||||
return price
|
||||
from_unit, to_unit = self.browse(cr, uid, [from_uom_id, to_uom_id])
|
||||
if from_unit.category_id.id != to_unit.category_id.id:
|
||||
@@ -890,11 +891,8 @@ class product_product(osv.osv):
|
||||
return dict.fromkeys(ids, True)
|
||||
|
||||
def _get_name_template_ids(self, cr, uid, ids, context=None):
|
||||
result = set()
|
||||
template_ids = self.pool.get('product.product').search(cr, uid, [('product_tmpl_id', 'in', ids)])
|
||||
for el in template_ids:
|
||||
result.add(el)
|
||||
return list(result)
|
||||
return list(set(template_ids))
|
||||
|
||||
def _get_image_variant(self, cr, uid, ids, name, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
@@ -924,7 +922,7 @@ class product_product(osv.osv):
|
||||
|
||||
_columns = {
|
||||
'price': fields.function(_product_price, type='float', string='Price', digits_compute=dp.get_precision('Product Price')),
|
||||
'price_extra': fields.function(_get_price_extra, type='float', string='Variant Extra Price', help="This is the sum of the extra price of all attributes"),
|
||||
'price_extra': fields.function(_get_price_extra, type='float', string='Variant Extra Price', help="This is the sum of the extra price of all attributes", digits_compute=dp.get_precision('Product Price')),
|
||||
'lst_price': fields.function(_product_lst_price, fnct_inv=_set_product_lst_price, type='float', string='Public Price', digits_compute=dp.get_precision('Product Price')),
|
||||
'code': fields.function(_product_code, type='char', string='Internal Reference'),
|
||||
'partner_ref' : fields.function(_product_partner_ref, type='char', string='Customer ref'),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<filter string="Consumable" name="consumable" icon="terp-accessories-archiver" domain="[('type','=','consu')]" help="Consumable products"/>
|
||||
<separator/>
|
||||
<filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
|
||||
<field name="categ_id"/>
|
||||
<field name="categ_id" filter_domain="[('categ_id', 'child_of', self)]"/>
|
||||
<field string="Product Variant" name="product_variant_ids" filter_domain="['|', ('product_variant_ids.name','ilike',self), ('product_variant_ids.attribute_value_ids.name','ilike',self)]"/>
|
||||
<field name="company_id"/>
|
||||
<field name="pricelist_id" widget="selection" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/> <!-- Keep widget=selection on this field to pass numeric `self` value, which is not the case for regular m2o widgets! -->
|
||||
@@ -257,6 +257,11 @@
|
||||
<field string="List of Variants" name="product_variant_count" widget="statinfo" />
|
||||
</button>
|
||||
</div>
|
||||
<p class="oe_grey">
|
||||
<strong>Warning</strong>: adding or deleting attributes
|
||||
will delete and recreate existing variants and lead
|
||||
to the loss of its eventual customizations.
|
||||
</p>
|
||||
<field name="attribute_line_ids" widget="one2many_list" context="{'show_attribute': False}">
|
||||
<tree string="Variants" editable="bottom">
|
||||
<field name="attribute_id"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<lot-line type="fields" name="id">
|
||||
<code type="field" name="code"/>
|
||||
<product type="field" name="name"/>
|
||||
<variant type="field" name="attribute_value_ids"/>
|
||||
<variant type="field" name="attribute_value_ids.name"/>
|
||||
<price type="field" name="list_price"/>
|
||||
<barcode type="field" name="barcode"/>
|
||||
<currency type="field" name="company_id.currency_id.name"/>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<barCode><xsl:value-of select="barcode" /></barCode>
|
||||
</td>
|
||||
<td>
|
||||
<para style="nospace"><xsl:value-of select="substring(product, 1, pmaxChars)"/></para><xsl:text>, </xsl:text>
|
||||
<para style="nospace"><xsl:value-of select="substring(product, 1, $pmaxChars)"/></para><xsl:text>, </xsl:text>
|
||||
<para style="nospace"><xsl:value-of select="variant"/></para>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -16,6 +16,7 @@ access_product_pricelist_type_partner_manager,product.pricelist.type partner man
|
||||
access_product_pricelist_partner_manager,product.pricelist partner manager,model_product_pricelist,base.group_partner_manager,1,0,0,0
|
||||
access_product_product_employee,product.product employee,model_product_product,base.group_user,1,0,0,0
|
||||
access_product_price_history_employee,prices.history employee,model_product_price_history,base.group_user,1,0,0,0
|
||||
access_product_price_history_salemanager,prices.history sale manager,product.model_product_price_history,base.group_sale_manager,1,1,1,1
|
||||
access_product_template_sale_manager,product.template salemanager,model_product_template,base.group_sale_manager,1,1,1,1
|
||||
access_product_product_sale_manager,product.product salemanager,model_product_product,base.group_sale_manager,1,1,1,1
|
||||
access_product_category_sale_manager,product.category salemanager,product.model_product_category,base.group_sale_manager,1,1,1,1
|
||||
|
||||
|
@@ -15,6 +15,8 @@ class TestPricelist(TransactionCase):
|
||||
self.datacard_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_product_46')[1]
|
||||
self.unit_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_unit')[1]
|
||||
self.dozen_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_dozen')[1]
|
||||
self.tonne_id = self.ir_model_data.xmlid_to_res_id(cr, uid, 'product.product_uom_ton')
|
||||
self.kg_id = self.ir_model_data.xmlid_to_res_id(cr, uid, 'product.product_uom_kgm')
|
||||
|
||||
self.public_pricelist_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'list0')[1]
|
||||
self.sale_pricelist_id = self.product_pricelist.create(cr, uid, {
|
||||
@@ -64,7 +66,50 @@ class TestPricelist(TransactionCase):
|
||||
usb_adapter_unit = self.product_product.browse(cr, uid, self.usb_adapter_id, context=unit_context)
|
||||
usb_adapter_dozen = self.product_product.browse(cr, uid, self.usb_adapter_id, context=dozen_context)
|
||||
self.assertAlmostEqual(usb_adapter_unit.price*12, usb_adapter_dozen.price)
|
||||
|
||||
datacard_unit = self.product_product.browse(cr, uid, self.datacard_id, context=unit_context)
|
||||
datacard_dozen = self.product_product.browse(cr, uid, self.datacard_id, context=dozen_context)
|
||||
# price_surcharge applies to product default UoM, here "Units", so surcharge will be multiplied
|
||||
self.assertAlmostEqual(datacard_unit.price*12, datacard_dozen.price)
|
||||
|
||||
def test_20_pricelist_uom(self):
|
||||
# Verify that the pricelist rules are correctly using the product's default UoM
|
||||
# as reference, and return a result according to the target UoM (as specific in the context)
|
||||
cr, uid = self.cr, self.uid
|
||||
kg, tonne = self.kg_id, self.tonne_id
|
||||
tonne_price = 100
|
||||
|
||||
# make sure 'tonne' resolves down to 1 'kg'.
|
||||
self.uom.write(cr, uid, tonne, {'rounding': 0.001})
|
||||
|
||||
# setup product stored in 'tonnes', with a discounted pricelist for qty > 3 tonnes
|
||||
spam_id = self.product_product.copy(cr, uid, self.usb_adapter_id,
|
||||
{ 'name': '1 tonne of spam',
|
||||
'uom_id': self.tonne_id,
|
||||
'uos_id': self.tonne_id,
|
||||
'uom_po_id': self.tonne_id,
|
||||
'list_price': tonne_price,
|
||||
})
|
||||
pricelist_version_id = self.ir_model_data.xmlid_to_res_id(cr, uid, 'product.ver0')
|
||||
self.registry('product.pricelist.item').create(cr, uid,
|
||||
{ 'price_version_id': pricelist_version_id,
|
||||
'sequence': 10,
|
||||
'name': '3+ tonnes: -10 EUR discount/t',
|
||||
'base': 1, # based on public price
|
||||
'min_quantity': 3, # min = 3 tonnes
|
||||
'price_surcharge': -10, # -10 EUR / tonne
|
||||
'product_id': spam_id,
|
||||
})
|
||||
pricelist_id = self.public_pricelist_id
|
||||
|
||||
def test_unit_price(qty, uom, expected_unit_price):
|
||||
unit_price = self.registry('product.pricelist').price_get(cr, uid, [pricelist_id],
|
||||
spam_id, qty,
|
||||
context={'uom': uom})[pricelist_id]
|
||||
self.assertAlmostEqual(unit_price, expected_unit_price, msg='Computed unit price is wrong')
|
||||
|
||||
# Test prices - they are *per unit*, the quantity is only here to match the pricelist rules!
|
||||
test_unit_price(2, kg, tonne_price / 1000.0)
|
||||
test_unit_price(2000, kg, tonne_price / 1000.0)
|
||||
test_unit_price(3500, kg, (tonne_price - 10) / 1000.0)
|
||||
test_unit_price(2, tonne, tonne_price)
|
||||
test_unit_price(3, tonne, tonne_price - 10)
|
||||
|
||||
@@ -317,7 +317,7 @@
|
||||
<field name="name">project.project.gantt</field>
|
||||
<field name="model">project.project</field>
|
||||
<field name="arch" type="xml">
|
||||
<gantt date_delay="planned_hours" date_start="date_start" progress="progress_rate" string="Projects">
|
||||
<gantt date_start="date_start" date_stop="date" progress="progress_rate" string="Projects">
|
||||
</gantt>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -196,7 +196,6 @@
|
||||
<kanban default_group_by="stage_id">
|
||||
<field name="stage_id" options='{"group_by_tooltip": {"description": "Description", "legend_priority": "Use of stars"}}'/>
|
||||
<field name="color"/>
|
||||
<field name="priority"/>
|
||||
<field name="user_email"/>
|
||||
<field name="user_id"/>
|
||||
<field name="date_deadline"/>
|
||||
|
||||
@@ -30,8 +30,8 @@ class res_partner(osv.osv):
|
||||
Invoice = self.pool['account.invoice']
|
||||
return {
|
||||
partner_id: {
|
||||
'purchase_order_count': PurchaseOrder.search_count(cr,uid, [('partner_id', '=', partner_id)], context=context),
|
||||
'supplier_invoice_count': Invoice.search_count(cr,uid, [('partner_id', '=', partner_id), ('type','=','in_invoice')], context=context)
|
||||
'purchase_order_count': PurchaseOrder.search_count(cr,uid, [('partner_id', 'child_of', partner_id)], context=context),
|
||||
'supplier_invoice_count': Invoice.search_count(cr,uid, [('partner_id', 'child_of', partner_id), ('type','=','in_invoice')], context=context)
|
||||
}
|
||||
for partner_id in ids
|
||||
}
|
||||
|
||||
@@ -296,7 +296,8 @@ class purchase_order(osv.osv):
|
||||
'bid_validity': fields.date('Bid Valid Until', help="Date on which the bid expired"),
|
||||
'picking_type_id': fields.many2one('stock.picking.type', 'Deliver To', help="This will determine picking type of incoming shipment", required=True,
|
||||
states={'confirmed': [('readonly', True)], 'approved': [('readonly', True)], 'done': [('readonly', True)]}),
|
||||
'related_location_id': fields.related('picking_type_id', 'default_location_dest_id', type='many2one', relation='stock.location', string="Related location", store=True),
|
||||
'related_location_id': fields.related('picking_type_id', 'default_location_dest_id', type='many2one', relation='stock.location', string="Related location", store=True),
|
||||
'related_usage': fields.related('location_id', 'usage', type='char'),
|
||||
'shipment_count': fields.function(_count_all, type='integer', string='Incoming Shipments', multi=True),
|
||||
'invoice_count': fields.function(_count_all, type='integer', string='Invoices', multi=True),
|
||||
'group_id': fields.many2one('procurement.group', string="Procurement Group"),
|
||||
@@ -383,8 +384,8 @@ class purchase_order(osv.osv):
|
||||
if picking_type_id:
|
||||
picktype = self.pool.get("stock.picking.type").browse(cr, uid, picking_type_id, context=context)
|
||||
if picktype.default_location_dest_id:
|
||||
value.update({'location_id': picktype.default_location_dest_id.id})
|
||||
value.update({'related_location_id': picktype.default_location_dest_id and picktype.default_location_dest_id.id or False})
|
||||
value.update({'location_id': picktype.default_location_dest_id.id, 'related_usage': picktype.default_location_dest_id.usage})
|
||||
value.update({'related_location_id': picktype.default_location_dest_id.id})
|
||||
return {'value': value}
|
||||
|
||||
def onchange_partner_id(self, cr, uid, ids, partner_id, context=None):
|
||||
@@ -745,14 +746,14 @@ class purchase_order(osv.osv):
|
||||
'product_uos_qty': min(procurement_qty, diff_quantity),
|
||||
'move_dest_id': procurement.move_dest_id.id, #move destination is same as procurement destination
|
||||
'procurement_id': procurement.id,
|
||||
'invoice_state': procurement.rule_id.invoice_state or (procurement.location_id and procurement.location_id.usage == 'customer' and procurement.invoice_state=='picking' and '2binvoiced') or (order.invoice_method == 'picking' and '2binvoiced') or 'none', #dropship case takes from sale
|
||||
'invoice_state': procurement.rule_id.invoice_state or (procurement.location_id and procurement.location_id.usage == 'customer' and procurement.invoice_state=='2binvoiced' and '2binvoiced') or (order.invoice_method == 'picking' and '2binvoiced') or 'none', #dropship case takes from sale
|
||||
'propagate': procurement.rule_id.propagate,
|
||||
})
|
||||
diff_quantity -= min(procurement_qty, diff_quantity)
|
||||
res.append(tmp)
|
||||
#if the order line has a bigger quantity than the procurement it was for (manually changed or minimal quantity), then
|
||||
#split the future stock move in two because the route followed may be different.
|
||||
if diff_quantity > 0:
|
||||
if float_compare(diff_quantity, 0.0, precision_rounding=order_line.product_uom.rounding) > 0:
|
||||
move_template['product_uom_qty'] = diff_quantity
|
||||
move_template['product_uos_qty'] = diff_quantity
|
||||
res.append(move_template)
|
||||
@@ -1052,7 +1053,7 @@ class purchase_order_line(osv.osv):
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
|
||||
# Calculate the list of purchase orders first
|
||||
# We will group by PO first, so we do the check only once for each PO
|
||||
purchase_orders = list(set([x.order_id for x in self.browse(cr, uid, ids, context=context)]))
|
||||
for purchase in purchase_orders:
|
||||
if all([l.state == 'cancel' for l in purchase.order_line]):
|
||||
@@ -1063,7 +1064,6 @@ class purchase_order_line(osv.osv):
|
||||
res = [user for user in group_uom.users if user.id == uid]
|
||||
return len(res) and True or False
|
||||
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id,
|
||||
partner_id, date_order=False, fiscal_position_id=False, date_planned=False,
|
||||
name=False, price_unit=False, state='draft', context=None):
|
||||
|
||||
@@ -226,12 +226,12 @@
|
||||
<group>
|
||||
<field name="date_order"/>
|
||||
<field name="origin" attrs="{'invisible': [('origin','=',False)]}"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="picking_type_id" on_change="onchange_picking_type_id(picking_type_id, context)" domain="[('code','=','incoming')]" widget="selection" context="{'special_shortened_wh_name': True}" groups="stock.group_locations"/>
|
||||
<field name="related_location_id" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="picking_type_id" on_change="onchange_picking_type_id(picking_type_id, context)" domain="[('code','=','incoming')]" options="{'no_create': True}" context="{'special_shortened_wh_name': True}" groups="stock.group_locations"/>
|
||||
<field name="related_usage" invisible="1"/>
|
||||
<field name="dest_address_id" string="Customer Address" on_change="onchange_dest_address_id(dest_address_id, context)"
|
||||
attrs="{'invisible':['|', ('picking_type_id','=',False), ('related_location_id','!=', False)],
|
||||
'required': [('picking_type_id','!=',False), ('related_location_id','=', False)]}"
|
||||
attrs="{'invisible':[('related_usage','!=','customer')],
|
||||
'required': [('related_usage','=', 'customer')]}"
|
||||
groups="stock.group_locations"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -242,7 +242,7 @@
|
||||
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,0,False,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,False,parent.state,context)" context="{'partner_id': parent.partner_id}"/>
|
||||
<field name="name"/>
|
||||
<field name="date_planned"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="account_analytic_id" context="{'default_partner_id':parent.partner_id}" groups="purchase.group_analytic_accounting" domain="[('type','not in',('view','template'))]"/>
|
||||
<field name="product_qty" on_change="onchange_product_id(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id,parent.date_order,parent.fiscal_position,date_planned,name,False,parent.state,context)"/>
|
||||
<field name="product_uom" groups="product.group_uom" on_change="onchange_product_uom(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order,parent.fiscal_position,date_planned,name,False,parent.state,context)"/>
|
||||
@@ -434,7 +434,7 @@
|
||||
<field name="taxes_id" widget="many2many_tags" domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
|
||||
<field name="date_planned" widget="date"/>
|
||||
<field name="account_analytic_id" colspan="2" groups="purchase.group_analytic_accounting"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
@@ -499,7 +499,7 @@
|
||||
<field name="taxes_id" widget="many2many_tags"
|
||||
domain="[('parent_id','=',False),('type_tax_use','!=','sale')]"/>
|
||||
<field name="date_planned" widget="date" readonly="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="account_analytic_id" colspan="4" groups="purchase.group_analytic_accounting"/>
|
||||
<field name="invoiced"/>
|
||||
</group>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
@@ -39,10 +40,12 @@ class stock_move(osv.osv):
|
||||
for move in self.browse(cr, uid, ids, context=context):
|
||||
if move.purchase_line_id and move.purchase_line_id.order_id:
|
||||
order_id = move.purchase_line_id.order_id.id
|
||||
# update linked purchase order as superuser as the warehouse
|
||||
# user may not have rights to access purchase.order
|
||||
if self.pool.get('purchase.order').test_moves_done(cr, uid, [order_id], context=context):
|
||||
workflow.trg_validate(uid, 'purchase.order', order_id, 'picking_done', cr)
|
||||
workflow.trg_validate(SUPERUSER_ID, 'purchase.order', order_id, 'picking_done', cr)
|
||||
if self.pool.get('purchase.order').test_moves_except(cr, uid, [order_id], context=context):
|
||||
workflow.trg_validate(uid, 'purchase.order', order_id, 'picking_cancel', cr)
|
||||
workflow.trg_validate(SUPERUSER_ID, 'purchase.order', order_id, 'picking_cancel', cr)
|
||||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
@@ -158,6 +161,16 @@ class stock_picking(osv.osv):
|
||||
invoice_line_obj.write(cr, uid, inv_lines, {'invoice_id': invoice_id}, context=context)
|
||||
return invoice_id
|
||||
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, move, context=None):
|
||||
inv_vals = super(stock_picking, self)._get_invoice_vals(cr, uid, key, inv_type, journal_id, move, context=context)
|
||||
if move.purchase_line_id and move.purchase_line_id.order_id:
|
||||
purchase = move.purchase_line_id.order_id
|
||||
inv_vals.update({
|
||||
'fiscal_position': purchase.fiscal_position.id,
|
||||
'payment_term': purchase.payment_term_id.id,
|
||||
})
|
||||
return inv_vals
|
||||
|
||||
|
||||
class stock_warehouse(osv.osv):
|
||||
_inherit = 'stock.warehouse'
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
<div class="oe_structure"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
Shipping address :<br/>
|
||||
<strong>Shipping address:</strong>
|
||||
<div t-if="o.dest_address_id">
|
||||
<div t-field="o.dest_address_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
</div>
|
||||
|
||||
<div t-if="o.picking_type_id and o.picking_type_id.warehouse_id">
|
||||
<div t-if="not o.dest_address_id and o.picking_type_id and o.picking_type_id.warehouse_id">
|
||||
<span t-field="o.picking_type_id.warehouse_id.name"/>
|
||||
<div t-field="o.picking_type_id.warehouse_id.partner_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
|
||||
<div class="row mt32 mb32">
|
||||
<div class="col-xs-6">
|
||||
Shipping address :<br/>
|
||||
<strong>Shipping address:</strong>
|
||||
<div t-if="o.dest_address_id">
|
||||
<div t-field="o.dest_address_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
</div>
|
||||
<div t-if="o.picking_type_id.warehouse_id">
|
||||
<div t-if="not o.dest_address_id and o.picking_type_id.warehouse_id">
|
||||
<span t-field="o.picking_type_id.warehouse_id.name"/>
|
||||
<div t-field="o.picking_type_id.warehouse_id.partner_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
from openerp.addons.web.http import Controller, route, request
|
||||
from openerp.addons.web.controllers.main import _serialize_exception
|
||||
from openerp.osv import osv
|
||||
from openerp.tools import html_escape
|
||||
|
||||
import simplejson
|
||||
from werkzeug import exceptions, url_decode
|
||||
@@ -71,7 +72,7 @@ class ReportController(Controller):
|
||||
# Misc. route utils
|
||||
#------------------------------------------------------
|
||||
@route(['/report/barcode', '/report/barcode/<type>/<path:value>'], type='http', auth="user")
|
||||
def report_barcode(self, type, value, width=600, height=100):
|
||||
def report_barcode(self, type, value, width=600, height=100, humanreadable=0):
|
||||
"""Contoller able to render barcode images thanks to reportlab.
|
||||
Samples:
|
||||
<img t-att-src="'/report/barcode/QR/%s' % o.name"/>
|
||||
@@ -81,11 +82,14 @@ class ReportController(Controller):
|
||||
:param type: Accepted types: 'Codabar', 'Code11', 'Code128', 'EAN13', 'EAN8', 'Extended39',
|
||||
'Extended93', 'FIM', 'I2of5', 'MSI', 'POSTNET', 'QR', 'Standard39', 'Standard93',
|
||||
'UPCA', 'USPS_4State'
|
||||
:param humanreadable: Accepted values: 0 (default) or 1. 1 will insert the readable value
|
||||
at the bottom of the output image
|
||||
"""
|
||||
try:
|
||||
width, height = int(width), int(height)
|
||||
width, height, humanreadable = int(width), int(height), bool(humanreadable)
|
||||
barcode = createBarcodeDrawing(
|
||||
type, value=value, format='png', width=width, height=height
|
||||
type, value=value, format='png', width=width, height=height,
|
||||
humanReadable = humanreadable
|
||||
)
|
||||
barcode = barcode.asString('png')
|
||||
except (ValueError, AttributeError):
|
||||
@@ -130,14 +134,14 @@ class ReportController(Controller):
|
||||
return response
|
||||
else:
|
||||
return
|
||||
except osv.except_osv, e:
|
||||
except Exception, e:
|
||||
se = _serialize_exception(e)
|
||||
error = {
|
||||
'code': 200,
|
||||
'message': "Odoo Server Error",
|
||||
'data': se
|
||||
}
|
||||
return request.make_response(simplejson.dumps(error))
|
||||
return request.make_response(html_escape(simplejson.dumps(error)))
|
||||
|
||||
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
|
||||
def check_wkhtmltopdf(self):
|
||||
|
||||
@@ -519,7 +519,7 @@ class Report(osv.Model):
|
||||
|
||||
if specific_paperformat_args and specific_paperformat_args.get('data-report-margin-top'):
|
||||
command_args.extend(['--margin-top', str(specific_paperformat_args['data-report-margin-top'])])
|
||||
elif paperformat.margin_top:
|
||||
else:
|
||||
command_args.extend(['--margin-top', str(paperformat.margin_top)])
|
||||
|
||||
if specific_paperformat_args and specific_paperformat_args.get('data-report-dpi'):
|
||||
@@ -536,12 +536,9 @@ class Report(osv.Model):
|
||||
elif paperformat.header_spacing:
|
||||
command_args.extend(['--header-spacing', str(paperformat.header_spacing)])
|
||||
|
||||
if paperformat.margin_left:
|
||||
command_args.extend(['--margin-left', str(paperformat.margin_left)])
|
||||
if paperformat.margin_bottom:
|
||||
command_args.extend(['--margin-bottom', str(paperformat.margin_bottom)])
|
||||
if paperformat.margin_right:
|
||||
command_args.extend(['--margin-right', str(paperformat.margin_right)])
|
||||
command_args.extend(['--margin-left', str(paperformat.margin_left)])
|
||||
command_args.extend(['--margin-bottom', str(paperformat.margin_bottom)])
|
||||
command_args.extend(['--margin-right', str(paperformat.margin_right)])
|
||||
if paperformat.orientation:
|
||||
command_args.extend(['--orientation', str(paperformat.orientation)])
|
||||
if paperformat.header_line:
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
############################################################################
|
||||
|
||||
import faces.pcalendar as pcal
|
||||
import matplotlib.cbook as cbook
|
||||
import openerp.tools as tools
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
@@ -73,7 +73,7 @@ class TimeScale(object):
|
||||
def create_time_slots(day):
|
||||
src_slots = dcal.get_working_times(day)
|
||||
slots = [0, src_slots, 24*60]
|
||||
slots = tuple(cbook.flatten(slots))
|
||||
slots = tuple(tools.flatten(slots))
|
||||
slots = zip(slots[:-1], slots[1:])
|
||||
|
||||
#balance non working slots
|
||||
|
||||
@@ -7,7 +7,7 @@ import json
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
from openerp.tools.float_utils import float_repr
|
||||
|
||||
class crm_team(osv.Model):
|
||||
_inherit = 'crm.team'
|
||||
@@ -37,7 +37,10 @@ class crm_team(osv.Model):
|
||||
res = {}
|
||||
for id in ids:
|
||||
created_domain = [('team_id', '=', id), ('state', 'not in', ['draft', 'cancel']), ('date', '>=', date_begin), ('date', '<=', date_end)]
|
||||
res[id] = json.dumps(self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context))
|
||||
values = self.__get_bar_values(cr, uid, obj, created_domain, ['price_total', 'date'], 'price_total', 'date', context=context)
|
||||
for value in values:
|
||||
value['value'] = float_repr(value.get('value', 0), precision_digits=self.pool['decimal.precision'].precision_get(cr, uid, 'Account'))
|
||||
res[id] = json.dumps(values)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
|
||||
@@ -41,9 +41,6 @@ access_product_group_res_partner_sale_manager,res_partner group_sale_manager,bas
|
||||
access_product_pricelist_version_sale_manager,product.pricelist.version sale_manager,product.model_product_pricelist_version,base.group_sale_manager,1,1,1,1
|
||||
access_account_invoice_report_salesman,account.invoice.report salesman,account.model_account_invoice_report,base.group_sale_salesman,1,0,0,0
|
||||
access_account_move_line_salesman,account.move.line invoice,account.model_account_move_line,base.group_sale_salesman,1,0,0,0
|
||||
access_product_price_history_salemanager,prices.history sale manager,product.model_product_price_history,base.group_sale_manager,1,1,1,1
|
||||
access_product_price_history_account_user,prices.history account user,product.model_product_price_history,account.group_account_user,1,0,0,0
|
||||
access_product_price_history_sale_use,prices.history sale use,product.model_product_price_history,base.group_sale_salesman,1,0,0,0
|
||||
access_sale_order_invoicing_payments,sale.order,model_sale_order,account.group_account_invoice,1,1,0,0
|
||||
access_sale_order_line_invoicing_payments,sale.order.line,model_sale_order_line,account.group_account_invoice,1,1,0,0
|
||||
access_account_invoice_report_invoicing_payments,account.invoice.report,account.model_account_invoice_report,account.group_account_invoice,1,0,0,0
|
||||
|
@@ -7,13 +7,13 @@
|
||||
<div class="oe_structure"/>
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<p t-if="o.partner_shipping_id == o.partner_invoice_id">Invoice and shipping address:</p>
|
||||
<p t-if="o.partner_shipping_id != o.partner_invoice_id">Invoice address: </p>
|
||||
<strong t-if="o.partner_shipping_id == o.partner_invoice_id">Invoice and shipping address:</strong>
|
||||
<strong t-if="o.partner_shipping_id != o.partner_invoice_id">Invoice address:</strong>
|
||||
<div t-field="o.partner_invoice_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
<div t-if="o.partner_shipping_id != o.partner_invoice_id">
|
||||
<p>Shipping address :</p>
|
||||
<div t-if="o.partner_shipping_id != o.partner_invoice_id" class="mt8">
|
||||
<strong>Shipping address:</strong>
|
||||
<div t-field="o.partner_shipping_id"
|
||||
t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true}'/>
|
||||
<p t-if="o.partner_id.vat">VAT: <span t-field="o.partner_id.vat"/></p>
|
||||
@@ -117,7 +117,7 @@
|
||||
</div>
|
||||
|
||||
<p t-field="o.note" />
|
||||
<p t-if="o.payment_term">
|
||||
<p t-if="o.payment_term.note">
|
||||
<span t-field="o.payment_term.note"/>
|
||||
</p>
|
||||
<p t-if="not o.payment_term and o.partner_id.property_payment_term">
|
||||
|
||||
@@ -52,10 +52,7 @@ class sale_order_line(osv.osv):
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
res[line.id] = 0
|
||||
if line.product_id:
|
||||
if line.purchase_price:
|
||||
res[line.id] = round((line.price_unit*line.product_uos_qty*(100.0-line.discount)/100.0) -(line.purchase_price*line.product_uos_qty), 2)
|
||||
else:
|
||||
res[line.id] = round((line.price_unit*line.product_uos_qty*(100.0-line.discount)/100.0) -(line.product_id.standard_price*line.product_uos_qty), 2)
|
||||
res[line.id] = round(line.price_subtotal - ((line.purchase_price or line.product_id.standard_price) * line.product_uos_qty), 2)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
|
||||
@@ -397,6 +397,8 @@ class stock_move(osv.osv):
|
||||
sale_line.order_id.partner_id, context=context)[sale_line.order_id.pricelist_id.id]
|
||||
else:
|
||||
res['price_unit'] = sale_line.price_unit
|
||||
uos_coeff = move.product_uom_qty and move.product_uos_qty / move.product_uom_qty or 1.0
|
||||
res['price_unit'] = res['price_unit'] / uos_coeff
|
||||
return res
|
||||
|
||||
|
||||
@@ -450,6 +452,18 @@ class stock_picking(osv.osv):
|
||||
invoice_line_obj.write(cr, uid, created_lines, {'invoice_id': invoice_id}, context=context)
|
||||
return invoice_id
|
||||
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, move, context=None):
|
||||
inv_vals = super(stock_picking, self)._get_invoice_vals(cr, uid, key, inv_type, journal_id, move, context=context)
|
||||
sale = move.picking_id.sale_id
|
||||
if sale:
|
||||
inv_vals.update({
|
||||
'fiscal_position': sale.fiscal_position.id,
|
||||
'payment_term': sale.payment_term.id,
|
||||
'user_id': sale.user_id.id,
|
||||
'team_id': sale.team_id.id,
|
||||
'name': sale.client_order_ref or '',
|
||||
})
|
||||
return inv_vals
|
||||
|
||||
class account_invoice(osv.Model):
|
||||
_inherit = 'account.invoice'
|
||||
|
||||
@@ -33,6 +33,12 @@
|
||||
<field name="picking_policy" required="True"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='order_line']/form//field[@name='product_id']" position="replace">
|
||||
<field name="product_id"
|
||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
|
||||
groups="base.group_user"
|
||||
on_change="product_id_change_with_wh(parent.pricelist_id,product_id,product_uom_qty,False,product_uos_qty,False,name,parent.partner_id, False, True, parent.date_order, product_packaging, parent.fiscal_position, False, parent.warehouse_id, context)"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="replace">
|
||||
<field name="product_id"
|
||||
context="{'partner_id':parent.partner_id, 'quantity':product_uom_qty, 'pricelist':parent.pricelist_id, 'uom':product_uom}"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
{
|
||||
'name': 'Sale Team',
|
||||
'name': 'Sales Teams',
|
||||
'version': '1.0',
|
||||
'author': 'OpenERP SA',
|
||||
'category': 'Sales Management',
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT, float_compare, float_round
|
||||
from openerp import SUPERUSER_ID
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from datetime import datetime
|
||||
@@ -498,20 +498,21 @@ class procurement_order(osv.osv):
|
||||
prods = prod_qty[op.product_id.id]['virtual_available']
|
||||
if prods is None:
|
||||
continue
|
||||
if prods <= op.product_min_qty:
|
||||
if float_compare(prods, op.product_min_qty, precision_rounding=op.product_uom.rounding) <= 0:
|
||||
qty = max(op.product_min_qty, op.product_max_qty) - prods
|
||||
reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0
|
||||
if reste > 0:
|
||||
if float_compare(reste, 0.0, precision_rounding=op.product_uom.rounding) > 0:
|
||||
qty += op.qty_multiple - reste
|
||||
|
||||
if qty < 0:
|
||||
if float_compare(qty, 0.0, precision_rounding=op.product_uom.rounding) < 0:
|
||||
continue
|
||||
|
||||
qty -= subtract_qty[op.id]
|
||||
|
||||
if qty >= 0:
|
||||
qty_rounded = float_round(qty, precision_rounding=op.product_uom.rounding)
|
||||
if qty_rounded >= 0:
|
||||
proc_id = procurement_obj.create(cr, uid,
|
||||
self._prepare_orderpoint_procurement(cr, uid, op, qty, context=context),
|
||||
self._prepare_orderpoint_procurement(cr, uid, op, qty_rounded, context=context),
|
||||
context=context)
|
||||
tot_procs.append(proc_id)
|
||||
if use_new_cursor:
|
||||
|
||||
@@ -466,12 +466,14 @@ function openerp_picking_widgets(instance){
|
||||
return new instance.web.Model('stock.picking.type').get_func('search_read')([],[])
|
||||
.then(function(types){
|
||||
self.picking_types = types;
|
||||
type_ids = [];
|
||||
for(var i = 0; i < types.length; i++){
|
||||
self.pickings_by_type[types[i].id] = [];
|
||||
type_ids.push(types[i].id);
|
||||
}
|
||||
self.pickings_by_type[0] = [];
|
||||
|
||||
return new instance.web.Model('stock.picking').call('search_read',[ [['state','in', ['assigned', 'partially_available']]], [] ], {context: new instance.web.CompoundContext()});
|
||||
return new instance.web.Model('stock.picking').call('search_read',[ [['state','in', ['assigned', 'partially_available']], ['picking_type_id', 'in', type_ids]], [] ], {context: new instance.web.CompoundContext()});
|
||||
|
||||
}).then(function(pickings){
|
||||
self.pickings = pickings;
|
||||
@@ -873,7 +875,8 @@ function openerp_picking_widgets(instance){
|
||||
if (pack_op_ids.length !== 0){
|
||||
return new instance.web.Model('stock.picking')
|
||||
.call('action_pack',[[[self.picking.id]], pack_op_ids])
|
||||
.then(function(){
|
||||
.then(function(pack){
|
||||
//TODO: the functionality using current_package_id in context is not needed anymore
|
||||
instance.session.user_context.current_package_id = false;
|
||||
return self.refresh_ui(self.picking.id);
|
||||
});
|
||||
|
||||
@@ -1031,9 +1031,9 @@ class stock_picking(osv.osv):
|
||||
product_uom = {} # Determines UoM used in pack operations
|
||||
for move in picking.move_lines:
|
||||
if not product_uom.get(move.product_id.id):
|
||||
product_uom[move.product_id.id] = move.product_id.uom_id.id
|
||||
if move.product_uom.id != move.product_id.uom_id.id and move.product_uom.factor > product_uom[move.product_id.id]:
|
||||
product_uom[move.product_id.id] = move.product_uom.id
|
||||
product_uom[move.product_id.id] = move.product_id.uom_id
|
||||
if move.product_uom.id != move.product_id.uom_id.id and move.product_uom.factor > product_uom[move.product_id.id].factor:
|
||||
product_uom[move.product_id.id] = move.product_uom
|
||||
|
||||
pack_obj = self.pool.get("stock.quant.package")
|
||||
quant_obj = self.pool.get("stock.quant")
|
||||
@@ -1091,7 +1091,7 @@ class stock_picking(osv.osv):
|
||||
uom_id = product.uom_id.id
|
||||
qty_uom = qty
|
||||
if product_uom.get(key[0]):
|
||||
uom_id = product_uom[key[0]]
|
||||
uom_id = product_uom[key[0]].id
|
||||
qty_uom = uom_obj._compute_qty(cr, uid, product.uom_id.id, qty, uom_id)
|
||||
vals.append({
|
||||
'picking_id': picking.id,
|
||||
@@ -1274,7 +1274,7 @@ class stock_picking(osv.osv):
|
||||
#2) then, process the remaining part
|
||||
all_op_processed = True
|
||||
for ops, product_id, remaining_qty in still_to_do:
|
||||
all_op_processed = all_op_processed and _create_link_for_product(ops.id, product_id, remaining_qty)
|
||||
all_op_processed = _create_link_for_product(ops.id, product_id, remaining_qty) and all_op_processed
|
||||
return (need_rereserve, all_op_processed)
|
||||
|
||||
def picking_recompute_remaining_quantities(self, cr, uid, picking, context=None):
|
||||
@@ -1453,6 +1453,7 @@ class stock_picking(osv.osv):
|
||||
stock_operation_obj = self.pool.get('stock.pack.operation')
|
||||
package_obj = self.pool.get('stock.quant.package')
|
||||
stock_move_obj = self.pool.get('stock.move')
|
||||
package_id = False
|
||||
for picking_id in picking_ids:
|
||||
operation_search_domain = [('picking_id', '=', picking_id), ('result_package_id', '=', False)]
|
||||
if operation_filter_ids != []:
|
||||
@@ -1472,7 +1473,7 @@ class stock_picking(osv.osv):
|
||||
stock_move_obj.check_tracking_product(cr, uid, op.product_id, op.lot_id.id, op.location_id, op.location_dest_id, context=context)
|
||||
package_id = package_obj.create(cr, uid, {}, context=context)
|
||||
stock_operation_obj.write(cr, uid, pack_operation_ids, {'result_package_id': package_id}, context=context)
|
||||
return True
|
||||
return package_id
|
||||
|
||||
def process_product_id_from_ui(self, cr, uid, picking_id, product_id, op_id, increment=1, context=None):
|
||||
return self.pool.get('stock.pack.operation')._search_and_increment(cr, uid, picking_id, [('product_id', '=', product_id),('id', '=', op_id)], increment=increment, context=context)
|
||||
|
||||
@@ -146,7 +146,7 @@ watch your stock valuation, and track production lots (based on serial numbers).
|
||||
|
||||
<record id="warehouse0" model="stock.warehouse">
|
||||
<field model="res.company" name="name" search="[]" use="name"/>
|
||||
|
||||
<field name="partner_id" ref="base.main_partner"/>
|
||||
<field name="code">WH</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ class stock_change_product_qty(osv.osv_memory):
|
||||
'product_id': data.product_id.id,
|
||||
'location_id': data.location_id.id,
|
||||
'lot_id': data.lot_id.id}, context=context)
|
||||
product = data.product_id.with_context(location=data.location_id.id)
|
||||
product = data.product_id.with_context(location=data.location_id.id, lot_id= data.lot_id.id)
|
||||
th_qty = product.qty_available
|
||||
line_data = {
|
||||
'inventory_id': inventory_id,
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
<field name="product_id" invisible="1"/>
|
||||
<field name="location_id" groups="stock.group_locations"/>
|
||||
<field name="lot_id" context="{'search_default_product_id':product_id,'default_product_id':product_id}" groups="stock.group_production_lot"/>
|
||||
<p groups="stock.group_production_lot" class="oe_grey">
|
||||
When you select a serial number (lot), the quantity is corrected with respect to
|
||||
the quantity of that serial number (lot) and not to the total quantity of the product.
|
||||
</p>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="change_product_qty" string="_Apply" type="object" class="oe_highlight"/>
|
||||
|
||||
@@ -86,4 +86,15 @@ class stock_move_scrap(osv.osv_memory):
|
||||
move_obj.action_scrap(cr, uid, move_ids,
|
||||
data.product_qty, data.location_id.id, restrict_lot_id=data.restrict_lot_id.id,
|
||||
context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
if context.get('active_id'):
|
||||
move = self.pool.get('stock.move').browse(cr, uid, context['active_id'], context=context)
|
||||
return {
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'stock.picking',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_id': move.picking_id.id,
|
||||
'context': context
|
||||
}
|
||||
else:
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
@@ -250,7 +250,7 @@ class stock_picking(osv.osv):
|
||||
invoices += self._invoice_create_line(cr, uid, moves, journal_id, type, context=context)
|
||||
return invoices
|
||||
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, origin, context=None):
|
||||
def _get_invoice_vals(self, cr, uid, key, inv_type, journal_id, move, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
partner, currency_id, company_id, user_id = key
|
||||
@@ -261,7 +261,7 @@ class stock_picking(osv.osv):
|
||||
account_id = partner.property_account_payable.id
|
||||
payment_term = partner.property_supplier_payment_term.id or False
|
||||
return {
|
||||
'origin': origin,
|
||||
'origin': move.picking_id.name,
|
||||
'date_invoice': context.get('date_inv', False),
|
||||
'user_id': user_id,
|
||||
'partner_id': partner.id,
|
||||
@@ -284,12 +284,15 @@ class stock_picking(osv.osv):
|
||||
partner, user_id, currency_id = move_obj._get_master_data(cr, uid, move, company, context=context)
|
||||
|
||||
key = (partner, currency_id, company.id, user_id)
|
||||
invoice_vals = self._get_invoice_vals(cr, uid, key, inv_type, journal_id, move, context=context)
|
||||
|
||||
if key not in invoices:
|
||||
# Get account and payment terms
|
||||
invoice_vals = self._get_invoice_vals(cr, uid, key, inv_type, journal_id, origin, context=context)
|
||||
invoice_id = self._create_invoice_from_picking(cr, uid, move.picking_id, invoice_vals, context=context)
|
||||
invoices[key] = invoice_id
|
||||
else:
|
||||
invoice = invoice_obj.browse(cr, uid, invoices[key], context=context)
|
||||
invoice.write({'origin': '%s, %s' % (invoice.origin, invoice_vals['origin'],)})
|
||||
|
||||
invoice_line_vals = move_obj._get_invoice_line_vals(cr, uid, move, partner, inv_type, context=context)
|
||||
invoice_line_vals['invoice_id'] = invoices[key]
|
||||
@@ -309,4 +312,4 @@ class stock_picking(osv.osv):
|
||||
res.update({'invoice_state': op.picking_id.invoice_state})
|
||||
if op.linked_move_operation_ids:
|
||||
res.update({'price_unit': op.linked_move_operation_ids[-1].move_id.price_unit})
|
||||
return res
|
||||
return res
|
||||
|
||||
@@ -241,7 +241,7 @@ class stock_quant(osv.osv):
|
||||
'line_id': move_lines,
|
||||
'period_id': period_id,
|
||||
'date': move.date,
|
||||
'ref': move.picking_id and move.picking_id.name}, context=context)
|
||||
'ref': move.picking_id.name}, context=context)
|
||||
|
||||
#def _reconcile_single_negative_quant(self, cr, uid, to_solve_quant, quant, quant_neg, qty, context=None):
|
||||
# move = self._get_latest_move(cr, uid, to_solve_quant, context=context)
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
<xpath expr="//button[@name='do_unreserve']" position="after">
|
||||
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice" attrs="{'invisible': ['|',('state','<>','done'),('invoice_state','<>','2binvoiced')]}" type="action" class="oe_highlight" groups="base.group_user"/>
|
||||
</xpath>
|
||||
<field name="move_lines" position="attributes">
|
||||
<attribute name="context">{'default_invoice_state': invoice_state, 'address_in_id': partner_id, 'form_view_ref':'stock.view_move_picking_form', 'tree_view_ref':'stock.view_move_picking_tree', 'default_picking_type_id': picking_type_id,'default_picking_id': active_id}</attribute>
|
||||
</field>
|
||||
<xpath expr="//field[@name='move_type']" position="after">
|
||||
<field name="invoice_state" groups="account.group_account_invoice"/>
|
||||
</xpath>
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
<record id="picking_type_dropship" model="stock.picking.type">
|
||||
<field name="name">Dropship</field>
|
||||
<field name="sequence_id" ref="seq_picking_type_dropship"/>
|
||||
<field name="code">outgoing</field>
|
||||
<field name="code">incoming</field>
|
||||
<field name="warehouse_id" eval="False"/>
|
||||
<field name="default_location_src_id" ref="stock.stock_location_suppliers"/>
|
||||
<field name="default_location_dest_id" ref="stock.stock_location_customers"/>
|
||||
</record>
|
||||
|
||||
@@ -14,20 +14,20 @@
|
||||
type: product
|
||||
uom_id: product.product_uom_unit
|
||||
uom_po_id: product.product_uom_unit
|
||||
seller_ids:
|
||||
seller_ids:
|
||||
- delay: 1
|
||||
name: base.res_partner_2
|
||||
min_qty: 2.0
|
||||
qty: 10.0
|
||||
-
|
||||
Set routes on product to be MTO adn Buy
|
||||
Set routes on product to be MTO and Buy
|
||||
-
|
||||
!python {model: product.product}: |
|
||||
route_warehouse0_buy = self.pool.get('stock.warehouse').browse(cr, uid, ref('stock.warehouse0')).buy_pull_id.route_id.id
|
||||
route_warehouse0_mto = self.pool.get('stock.warehouse').browse(cr, uid, ref('stock.warehouse0')).mto_pull_id.route_id.id
|
||||
self.write(cr, uid, ref('product_mto'), { 'route_ids': [(6, 0, [route_warehouse0_mto,route_warehouse0_buy])]}, context=context )
|
||||
self.write(cr, uid, ref('product_mto'), { 'route_ids': [(6, 0, [route_warehouse0_mto,route_warehouse0_buy])]}, context=context )
|
||||
-
|
||||
Create a sales order with a line of 5 "My Product".
|
||||
Create a sales order with a line of 5 Units "My Product".
|
||||
-
|
||||
!record {model: sale.order, id: sale_order_product_mto}:
|
||||
partner_id: base.res_partner_3
|
||||
@@ -40,6 +40,21 @@
|
||||
Confirm the sale order
|
||||
-
|
||||
!workflow {model: sale.order, action: order_confirm, ref: sale_order_product_mto}
|
||||
-
|
||||
Create another sales order with 2 Dozen of the same product
|
||||
-
|
||||
!record {model: sale.order, id: sale_order_product_mto2}:
|
||||
partner_id: base.res_partner_4
|
||||
note: Create Sales order
|
||||
warehouse_id: wh_pps
|
||||
order_line:
|
||||
- product_id: product_mto
|
||||
product_uom_qty: 2.00
|
||||
product_uom: product.product_uom_dozen
|
||||
-
|
||||
Confirm the sale order
|
||||
-
|
||||
!workflow {model: sale.order, action: order_confirm, ref: sale_order_product_mto2}
|
||||
-
|
||||
I run scheduler.
|
||||
-
|
||||
@@ -62,11 +77,21 @@
|
||||
for procu in self.browse(cr,uid,procu_ids,context=context):
|
||||
assert procu.state == u'running', 'Procurement with id: %d should be running but is with state : %s!' %(procu.id, procu.state)
|
||||
|
||||
# Check that one or more Purchase order
|
||||
# Check that one purchase order has been created
|
||||
purchase_ids = [proc.purchase_line_id.order_id for proc in self.browse(cr, uid, procu_ids) if proc.purchase_line_id]
|
||||
assert len(purchase_ids) > 0, 'No purchase order found !'
|
||||
|
||||
# Cancel the main procurement
|
||||
assert len(purchase_ids) == 1, 'No purchase order found !'
|
||||
|
||||
# Check the total quantity on the purchase order which should be in Unit(s)
|
||||
purchase_line = purchase_ids[0].order_line[0]
|
||||
assert purchase_line.product_qty == 29.0, 'As we ordered 2 Dozen(s) and 5 Unit(s), total should be 29 Unit(s) and not %s' % (purchase_line.product_qty,)
|
||||
|
||||
# Let us cancel the procurement related to the 2nd sales order first and check that the 2 Dozen(s) are subtracted correctly
|
||||
so2 = self.pool.get('sale.order').browse(cr, uid, ref('sale_order_product_mto2'))
|
||||
self.cancel(cr, uid, [so2.order_line[0].procurement_ids[0].id], context=context)
|
||||
assert so2.order_line[0].procurement_ids[0].state == u'cancel', 'Main procurement should be cancelled !'
|
||||
assert purchase_line.product_qty == 5.0, 'As we ordered 2 Dozen(s) and 5 Unit(s) and cancelled the two Dozen, total should be 5 Unit(s) and not %s' % (purchase_line.product_qty,)
|
||||
|
||||
# Cancel the main procurement from the sale order in units
|
||||
main_procu_id = self.search(cr, uid, [('origin', '=', so.name)])
|
||||
assert len(main_procu_id) == 1, 'Main procurement not identified !'
|
||||
self.cancel(cr, uid, main_procu_id, context=context)
|
||||
@@ -76,6 +101,6 @@
|
||||
for procu in self.browse(cr, uid, procu_ids, context=context):
|
||||
assert procu.state == u'cancel', 'Procurement %d should be cancelled but is with a state : %s!' %(procu.id, procu.state)
|
||||
|
||||
# Check that the purchase order is well cancelled
|
||||
# Check that the purchase order is cancelled
|
||||
for po in self.pool.get('purchase.order').browse(cr, uid, [po.id for po in purchase_ids], context=context):
|
||||
assert po.state == u'cancel', 'Purchase order %d should be cancelled but is in state : %s!' %(po.id, po.state)
|
||||
|
||||
@@ -34,9 +34,12 @@ class stock_invoice_onshipping(osv.osv_memory):
|
||||
pick = pickings and pickings[0]
|
||||
src_usage = pick.move_lines[0].location_id.usage
|
||||
dest_usage = pick.move_lines[0].location_dest_id.usage
|
||||
pick_purchase = pick.move_lines and pick.move_lines[0].purchase_line_id and pick.move_lines[0].purchase_line_id.order_id.invoice_method == 'picking'
|
||||
if pick.picking_type_id.code == 'outgoing' and src_usage == 'supplier' and dest_usage == 'customer' and pick_purchase:
|
||||
return 'purchase'
|
||||
if src_usage == 'supplier' and dest_usage == 'customer':
|
||||
pick_purchase = pick.move_lines and pick.move_lines[0].purchase_line_id and pick.move_lines[0].purchase_line_id.order_id.invoice_method == 'picking'
|
||||
if pick_purchase:
|
||||
return 'purchase'
|
||||
else:
|
||||
return 'sale'
|
||||
else:
|
||||
return super(stock_invoice_onshipping, self)._get_journal_type(cr, uid, context=context)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user