[MERGE] forward port of branch 8.0 up to 2492503

This commit is contained in:
Christophe Simonis
2015-04-16 19:40:48 +02:00
18 changed files with 323 additions and 184 deletions
+14 -1
View File
@@ -266,7 +266,7 @@
<group>
<field domain="[('partner_id', '=', partner_id)]" name="partner_bank_id" on_change="onchange_partner_bank(partner_bank_id)"/>
<field name="user_id" string="Responsible" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'account.group_account_invoice']}"/>
<field name="name" invisible="1"/>
<field name="name" attrs="{'invisible': [('type', '=', 'in_invoice')]}"/>
<field name="payment_term" options="{'no_create': True}" on_change="onchange_payment_term_date_invoice(payment_term, date_invoice)"/>
</group>
<group>
@@ -516,6 +516,19 @@
<field name="search_view_id" ref="view_account_invoice_filter"/>
</record>
<record id="action_invoice_refund_out_tree_tree" model="ir.actions.act_window.view">
<field eval="1" name="sequence"/>
<field name="view_mode">tree</field>
<field name="act_window_id" ref="action_invoice_refund_out_tree"/>
</record>
<record id="action_invoice_refund_out_tree_form" model="ir.actions.act_window.view">
<field eval="2" name="sequence"/>
<field name="view_mode">form</field>
<field name="view_id" ref="invoice_form"/>
<field name="act_window_id" ref="action_invoice_refund_out_tree"/>
</record>
<record id="action_invoice_tree_pending_invoice" model="ir.actions.act_window">
<field name="name">Pending Invoice</field>
<field name="res_model">account.invoice</field>
+9 -2
View File
@@ -851,7 +851,12 @@ class account_move_line(osv.osv):
ret.append(ret_line)
return ret
def list_partners_to_reconcile(self, cr, uid, context=None):
def list_partners_to_reconcile(self, cr, uid, context=None, filter_domain=False):
line_ids = []
if filter_domain:
line_ids = self.search(cr, uid, filter_domain, context=context)
where_clause = filter_domain and "AND l.id = ANY(%s)" or ""
cr.execute(
"""SELECT partner_id FROM (
SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit, MAX(l.create_date) AS max_date
@@ -861,10 +866,12 @@ class account_move_line(osv.osv):
WHERE a.reconcile IS TRUE
AND l.reconcile_id IS NULL
AND l.state <> 'draft'
%s
GROUP BY l.partner_id, p.last_reconciliation_date
) AS s
WHERE debit > 0 AND credit > 0 AND (last_reconciliation_date IS NULL OR max_date > last_reconciliation_date)
ORDER BY last_reconciliation_date""")
ORDER BY last_reconciliation_date"""
% where_clause, (line_ids,))
ids = [x[0] for x in cr.fetchall()]
if not ids:
return []
@@ -1791,7 +1791,7 @@ openerp.account = function (instance) {
this.last_group_by = group_by;
this.old_search = _.bind(this._super, this);
var mod = new instance.web.Model("account.move.line", context, domain);
return mod.call("list_partners_to_reconcile", []).then(function(result) {
return mod.call("list_partners_to_reconcile", [context, domain]).then(function(result) {
var current = self.current_partner !== null ? self.partners[self.current_partner][0] : null;
self.partners = result;
var index = _.find(_.range(self.partners.length), function(el) {
+3 -2
View File
@@ -396,7 +396,7 @@ class crm_lead(format_address, osv.osv):
"""
stages_leads = {}
for lead in self.browse(cr, uid, ids, context=context):
stage_id = self.stage_find(cr, uid, [lead], lead.team_id.id or False, [('probability', '=', 0.0), ('fold', '=', True), ('sequence', '>', 1)], context=context)
stage_id = self.stage_find(cr, uid, [lead], lead.team_id.id or False, [('probability', '=', 0.0), ('on_change', '=', True), ('sequence', '>', 1)], context=context)
if stage_id:
if stages_leads.get(stage_id):
stages_leads[stage_id].append(lead.id)
@@ -415,7 +415,7 @@ class crm_lead(format_address, osv.osv):
"""
stages_leads = {}
for lead in self.browse(cr, uid, ids, context=context):
stage_id = self.stage_find(cr, uid, [lead], lead.team_id.id or False, [('probability', '=', 100.0), ('fold', '=', True)], context=context)
stage_id = self.stage_find(cr, uid, [lead], lead.team_id.id or False, [('probability', '=', 100.0), ('on_change', '=', True)], context=context)
if stage_id:
if stages_leads.get(stage_id):
stages_leads[stage_id].append(lead.id)
@@ -887,6 +887,7 @@ class crm_lead(format_address, osv.osv):
(tree_view or False, 'tree'), (False, 'kanban'),
(False, 'calendar'), (False, 'graph')],
'type': 'ir.actions.act_window',
'context': {'default_type': 'opportunity'}
}
def redirect_lead_view(self, cr, uid, lead_id, context=None):
@@ -154,14 +154,106 @@ class account_analytic_line(osv.osv):
price = 0.0
return price
def _prepare_cost_invoice(self, cr, uid, partner, company_id, currency_id, analytic_lines, context=None):
""" returns values used to create main invoice from analytic lines"""
account_payment_term_obj = self.pool['account.payment.term']
invoice_name = analytic_lines[0].account_id.name
date_due = False
if partner.property_payment_term:
pterm_list = account_payment_term_obj.compute(cr, uid,
partner.property_payment_term.id, value=1,
date_ref=time.strftime('%Y-%m-%d'))
if pterm_list:
pterm_list = [line[0] for line in pterm_list]
pterm_list.sort()
date_due = pterm_list[-1]
return {
'name': "%s - %s" % (time.strftime('%d/%m/%Y'), invoice_name),
'partner_id': partner.id,
'company_id': company_id,
'payment_term': partner.property_payment_term.id or False,
'account_id': partner.property_account_receivable.id,
'currency_id': currency_id,
'date_due': date_due,
'fiscal_position': partner.property_account_position.id
}
def _prepare_cost_invoice_line(self, cr, uid, invoice_id, product_id, uom, user_id,
factor_id, account, analytic_lines, journal_type, data, context=None):
product_obj = self.pool['product.product']
uom_context = dict(context or {}, uom=uom)
total_price = sum(l.amount for l in analytic_lines)
total_qty = sum(l.unit_amount for l in analytic_lines)
if data.get('product'):
# force product, use its public price
if isinstance(data['product'], (tuple, list)):
product_id = data['product'][0]
else:
product_id = data['product']
unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, total_qty, uom_context)
elif journal_type == 'general' and product_id:
# timesheets, use sale price
unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, total_qty, uom_context)
else:
# expenses, using price from amount field
unit_price = total_price*-1.0 / total_qty
factor = self.pool['hr_timesheet_invoice.factor'].browse(cr, uid, factor_id, context=uom_context)
factor_name = factor.customer_name
curr_invoice_line = {
'price_unit': unit_price,
'quantity': total_qty,
'product_id': product_id,
'discount': factor.factor,
'invoice_id': invoice_id,
'name': factor_name,
'uos_id': uom,
'account_analytic_id': account.id,
}
if product_id:
product = product_obj.browse(cr, uid, product_id, context=uom_context)
factor_name = product_obj.name_get(cr, uid, [product_id], context=uom_context)[0][1]
if factor.customer_name:
factor_name += ' - ' + factor.customer_name
general_account = product.property_account_income or product.categ_id.property_account_income_categ
if not general_account:
raise UserError(_("Configuration Error!") + '\n' + _("Please define income account for product '%s'.") % product.name)
taxes = product.taxes_id or general_account.tax_ids
tax = self.pool['account.fiscal.position'].map_tax(cr, uid, account.partner_id.property_account_position, taxes)
curr_invoice_line.update({
'invoice_line_tax_id': [(6, 0, tax)],
'name': factor_name,
'invoice_line_tax_id': [(6, 0, tax)],
'account_id': general_account.id,
})
note = []
for line in analytic_lines:
# set invoice_line_note
details = []
if data.get('date', False):
details.append(line['date'])
if data.get('time', False):
if line['product_uom_id']:
details.append("%s %s" % (line.unit_amount, line.product_uom_id.name))
else:
details.append("%s" % (line['unit_amount'], ))
if data.get('name', False):
details.append(line['name'])
if details:
note.append(u' - '.join(map(lambda x: unicode(x) or '', details)))
if note:
curr_invoice_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '', note)))
return curr_invoice_line
def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
analytic_account_obj = self.pool.get('account.analytic.account')
account_payment_term_obj = self.pool.get('account.payment.term')
invoice_obj = self.pool.get('account.invoice')
product_obj = self.pool.get('product.product')
invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
fiscal_pos_obj = self.pool.get('account.fiscal.position')
product_uom_obj = self.pool.get('product.uom')
invoice_line_obj = self.pool.get('account.invoice.line')
invoices = []
if context is None:
@@ -169,131 +261,62 @@ class account_analytic_line(osv.osv):
if data is None:
data = {}
journal_types = {}
# use key (partner/account, company, currency)
# creates one invoice per key
invoice_grouping = {}
currency_id = False
# prepare for iteration on journal and accounts
for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
if line.journal_id.type not in journal_types:
journal_types[line.journal_id.type] = set()
journal_types[line.journal_id.type].add(line.account_id.id)
for journal_type, account_ids in journal_types.items():
for account in analytic_account_obj.browse(cr, uid, list(account_ids), context=context):
partner = account.partner_id
for line in self.browse(cr, uid, ids, context=context):
key = (line.account_id.id,
line.account_id.company_id.id,
line.account_id.pricelist_id.currency_id.id)
invoice_grouping.setdefault(key, []).append(line)
for (key_id, company_id, currency_id), analytic_lines in invoice_grouping.items():
# key_id is an account.analytic.account
partner = analytic_lines[0].account_id.partner_id # will be the same for every line
curr_invoice = self._prepare_cost_invoice(cr, uid, partner, company_id, currency_id, analytic_lines, context=context)
invoice_context = dict(context,
lang=partner.lang,
force_company=company_id, # set force_company in context so the correct product properties are selected (eg. income account)
company_id=company_id) # set company_id in context, so the correct default journal will be selected
last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=invoice_context)
invoices.append(last_invoice)
# use key (product, uom, user, invoiceable, analytic account, journal type)
# creates one invoice line per key
invoice_lines_grouping = {}
for analytic_line in analytic_lines:
account = analytic_line.account_id
if (not partner) or not (account.pricelist_id):
raise UserError(_('Contract incomplete. Please fill in the Customer and Pricelist fields.'))
raise UserError(_('Contract incomplete. Please fill in the Customer and Pricelist fields for %s.') % (account.name))
date_due = False
if partner.property_payment_term:
pterm_list= account_payment_term_obj.compute(cr, uid,
partner.property_payment_term.id, value=1,
date_ref=time.strftime('%Y-%m-%d'))
if pterm_list:
pterm_list = [line[0] for line in pterm_list]
pterm_list.sort()
date_due = pterm_list[-1]
if not analytic_line.to_invoice:
raise UserError(_('Trying to invoice non invoiceable line for %s.') % (analytic_line.product_id.name))
curr_invoice = {
'name': time.strftime('%d/%m/%Y') + ' - '+account.name,
'partner_id': account.partner_id.id,
'company_id': account.company_id.id,
'payment_term': partner.property_payment_term.id or False,
'account_id': partner.property_account_receivable.id,
'currency_id': account.pricelist_id.currency_id.id,
'date_due': date_due,
'fiscal_position': account.partner_id.property_account_position.id
}
context2 = context.copy()
context2['lang'] = partner.lang
# set company_id in context, so the correct default journal will be selected
context2['force_company'] = curr_invoice['company_id']
# set force_company in context so the correct product properties are selected (eg. income account)
context2['company_id'] = curr_invoice['company_id']
key = (analytic_line.product_id.id,
analytic_line.product_uom_id.id,
analytic_line.user_id.id,
analytic_line.to_invoice.id,
analytic_line.account_id,
analytic_line.journal_id.type)
invoice_lines_grouping.setdefault(key, []).append(analytic_line)
last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
invoices.append(last_invoice)
# finally creates the invoice line
for (product_id, uom, user_id, factor_id, account, journal_type), lines_to_invoice in invoice_lines_grouping.items():
curr_invoice_line = self._prepare_cost_invoice_line(cr, uid, last_invoice,
product_id, uom, user_id, factor_id, account, lines_to_invoice,
journal_type, data, context=context)
cr.execute("""SELECT product_id, user_id, to_invoice, sum(amount), sum(unit_amount), product_uom_id
FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
WHERE account_id = %s
AND line.id IN %s AND journal.type = %s AND to_invoice IS NOT NULL
GROUP BY product_id, user_id, to_invoice, product_uom_id""", (account.id, tuple(ids), journal_type))
for product_id, user_id, factor_id, total_price, qty, uom in cr.fetchall():
context2.update({'uom': uom})
if data.get('product'):
# force product, use its public price
product_id = data['product'][0]
unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
elif journal_type == 'general' and product_id:
# timesheets, use sale price
unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
else:
# expenses, using price from amount field
unit_price = total_price*-1.0 / qty
factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
# factor_name = factor.customer_name and line_name + ' - ' + factor.customer_name or line_name
factor_name = factor.customer_name
curr_line = {
'price_unit': unit_price,
'quantity': qty,
'product_id': product_id or False,
'discount': factor.factor,
'invoice_id': last_invoice,
'name': factor_name,
'uos_id': uom,
'account_analytic_id': account.id,
}
product = product_obj.browse(cr, uid, product_id, context=context2)
if product:
factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
if factor.customer_name:
factor_name += ' - ' + factor.customer_name
general_account = product.property_account_income or product.categ_id.property_account_income_categ
if not general_account:
raise UserError(_("Configuration Error!") + '\n' + _("Please define income account for product '%s'.") % product.name)
taxes = product.taxes_id or general_account.tax_ids
tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
curr_line.update({
'invoice_line_tax_id': [(6,0,tax )],
'name': factor_name,
'invoice_line_tax_id': [(6,0,tax)],
'account_id': general_account.id,
})
#
# Compute for lines
#
cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))
line_ids = cr.dictfetchall()
note = []
for line in line_ids:
# set invoice_line_note
details = []
if data.get('date', False):
details.append(line['date'])
if data.get('time', False):
if line['product_uom_id']:
details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
else:
details.append("%s" % (line['unit_amount'], ))
if data.get('name', False):
details.append(line['name'])
if details:
note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
if note:
curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
invoice_line_obj.create(cr, uid, curr_line, context=context)
cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
self.invalidate_cache(cr, uid, ['invoice_id'], ids, context=context)
invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
invoice_line_obj.create(cr, uid, curr_invoice_line, context=context)
self.write(cr, uid, [l.id for l in analytic_lines], {'invoice_id': last_invoice}, context=context)
invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
return invoices
class hr_analytic_timesheet(osv.osv):
_inherit = "hr.analytic.timesheet"
def on_change_account_id(self, cr, uid, ids, account_id, user_id=False):
+1
View File
@@ -167,6 +167,7 @@
<field name="product_uom_qty" string="Quantity"/>
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
<field name="price_unit"/>
<field name="tax_id" domain="[('parent_id', '=', False), ('type_tax_use', '=', 'purchase')]" widget="many2many_tags"/>
<field name="to_invoice"/>
<field name="price_subtotal"/>
</tree>
+71 -34
View File
@@ -183,15 +183,20 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
},
},{
model: 'account.tax',
fields: ['name','amount', 'price_include', 'include_base_amount', 'type'],
fields: ['name','amount', 'price_include', 'include_base_amount', 'type', 'child_ids', 'child_depend', 'include_base_amount'],
domain: null,
loaded: function(self,taxes){
self.taxes = taxes;
loaded: function(self, taxes){
self.taxes = taxes;
self.taxes_by_id = {};
for (var i = 0; i < taxes.length; i++) {
self.taxes_by_id[taxes[i].id] = taxes[i];
}
_.each(taxes, function(tax){
self.taxes_by_id[tax.id] = tax;
});
_.each(self.taxes_by_id, function(tax) {
tax.child_taxes = {};
_.each(tax.child_ids, function(child_tax_id) {
tax.child_taxes[child_tax_id] = self.taxes_by_id[child_tax_id];
});
});
},
},{
model: 'pos.session',
@@ -1089,52 +1094,84 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
}
return taxes;
},
get_all_prices: function(){
compute_all: function(taxes, price_unit) {
var self = this;
var res = [];
var currency_rounding = this.pos.currency.rounding;
var base = this.get_base_price();
var totalTax = base;
var totalNoTax = base;
var product = this.get_product();
var taxes = this.get_applicable_taxes();
var taxtotal = 0;
var taxdetail = {};
_.each(taxes, function(tax) {
var base = price_unit;
_(taxes).each(function(tax) {
if (tax.price_include) {
var tmp;
if (tax.type === "percent") {
tmp = base - round_pr(base / (1 + tax.amount),currency_rounding);
tmp = round_pr(base - round_pr(base / (1 + tax.amount),currency_rounding),currency_rounding);
data = {amount:tmp, price_include:true, id: tax.id};
res.push(data);
} else if (tax.type === "fixed") {
tmp = round_pr(tax.amount * self.get_quantity(),currency_rounding);
data = {amount:tmp, price_include:true, id: tax.id};
res.push(data);
} else {
throw "This type of tax is not supported by the point of sale: " + tax.type;
}
tmp = round_pr(tmp,currency_rounding);
taxtotal += tmp;
totalNoTax -= tmp;
taxdetail[tax.id] = tmp;
} else {
var tmp;
if (tax.type === "percent") {
tmp = tax.amount * base;
tmp = round_pr(tax.amount * base, currency_rounding);
data = {amount:tmp, price_include:false, id: tax.id};
res.push(data);
} else if (tax.type === "fixed") {
tmp = tax.amount * self.get_quantity();
tmp = round_pr(tax.amount * self.get_quantity(), currency_rounding);
data = {amount:tmp, price_include:false, id: tax.id};
res.push(data);
} 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;
var base_amount = data.amount;
var child_amount = 0.0;
if (tax.child_depend) {
res.pop(); // do not use parent tax
child_tax = self.compute_all(tax.child_taxes, base_amount);
res.push(child_tax);
_(child_tax).each(function(child) {
child_amount += child.amount;
});
}
if (tax.include_base_amount) {
base += base_amount + child_amount;
}
taxtotal += tmp;
totalTax += tmp;
taxdetail[tax.id] = tmp;
}
});
return res;
},
get_all_prices: function(){
var base = round_pr(this.get_quantity() * this.get_unit_price() * (1.0 - (this.get_discount() / 100.0)), this.pos.currency.rounding);
var totalTax = base;
var totalNoTax = base;
var taxtotal = 0;
var product = this.get_product();
var taxes_ids = product.taxes_id;
var taxes = this.pos.taxes;
var taxdetail = {};
var product_taxes = [];
_(taxes_ids).each(function(el){
product_taxes.push(_.detect(taxes, function(t){
return t.id === el;
}));
});
var all_taxes = _(this.compute_all(product_taxes, base)).flatten();
_(all_taxes).each(function(tax) {
if (tax.price_include) {
totalNoTax -= tax.amount;
} else {
totalTax += tax.amount;
}
taxtotal += tax.amount;
taxdetail[tax.id] = tax.amount;
});
return {
"priceWithTax": totalTax,
"priceWithoutTax": totalNoTax,
+1 -1
View File
@@ -1031,7 +1031,7 @@ class task(osv.osv):
def set_remaining_time(self, cr, uid, ids, remaining_time=1.0, context=None):
for task in self.browse(cr, uid, ids, context=context):
if (task.stage_id and task.stage_id.sequence <= 1) or (task.planned_hours == 0.0):
self.write(cr, uid, [task.id], {'planned_hours': remaining_time}, context=context)
self.write(cr, uid, [task.id], {'planned_hours': remaining_time + task.effective_hours}, context=context)
self.write(cr, uid, ids, {'remaining_hours': remaining_time}, context=context)
return True
+7 -6
View File
@@ -861,7 +861,7 @@ class purchase_order(osv.osv):
Orders will only be merged if:
* Purchase Orders are in draft
* Purchase Orders belong to the same partner
* Purchase Orders are have same stock location, same pricelist
* Purchase Orders are have same stock location, same pricelist, same currency
Lines will only be merged if:
* Order lines are exactly the same except for the quantity and unit
@@ -897,12 +897,13 @@ class purchase_order(osv.osv):
# Compute what the new orders should contain
new_orders = {}
order_lines_to_move = []
order_lines_to_move = {}
for porder in [order for order in self.browse(cr, uid, ids, context=context) if order.state == 'draft']:
order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id'))
order_key = make_key(porder, ('partner_id', 'location_id', 'pricelist_id', 'currency_id'))
new_order = new_orders.setdefault(order_key, ({}, []))
new_order[1].append(porder.id)
order_infos = new_order[0]
order_lines_to_move.setdefault(order_key, [])
if not order_infos:
order_infos.update({
@@ -913,6 +914,7 @@ class purchase_order(osv.osv):
'picking_type_id': porder.picking_type_id.id,
'location_id': porder.location_id.id,
'pricelist_id': porder.pricelist_id.id,
'currency_id': porder.currency_id.id,
'state': 'draft',
'order_line': {},
'notes': '%s' % (porder.notes or '',),
@@ -926,8 +928,7 @@ class purchase_order(osv.osv):
if porder.origin:
order_infos['origin'] = (order_infos['origin'] or '') + ' ' + porder.origin
for order_line in porder.order_line:
order_lines_to_move += [order_line.id]
order_lines_to_move[order_key] += [order_line.id for order_line in porder.order_line]
allorders = []
orders_info = {}
@@ -941,7 +942,7 @@ class purchase_order(osv.osv):
for key, value in order_data['order_line'].iteritems():
del value['uom_factor']
value.update(dict(key))
order_data['order_line'] = [(6, 0, order_lines_to_move)]
order_data['order_line'] = [(6, 0, order_lines_to_move[order_key])]
# create the new order
context.update({'mail_create_nolog': True})
@@ -13,7 +13,7 @@ Please note that: &#10; &#10;
Orders will only be merged if: &#10;
* Purchase Orders are in draft &#10;
* Purchase Orders belong to the same supplier &#10;
* Purchase Orders are have same stock location, same pricelist &#10; &#10;
* Purchase Orders are have same stock location, same pricelist, same currency &#10; &#10;
Lines will only be merged if: &#10;
* Order lines are exactly the same except for the product,quantity and unit &#10;
" colspan="4"/>
+4 -3
View File
@@ -330,7 +330,8 @@ class sale_order(osv.osv):
part = self.pool.get('res.partner').browse(cr, uid, part, context=context)
addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact'])
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
payment_term = part.property_payment_term and part.property_payment_term.id or False
invoice_part = self.pool.get('res.partner').browse(cr, uid, addr['invoice'], context=context)
payment_term = invoice_part.property_payment_term and invoice_part.property_payment_term.id or False
dedicated_salesman = part.user_id and part.user_id.id or uid
val = {
'partner_invoice_id': addr['invoice'],
@@ -393,14 +394,14 @@ class sale_order(osv.osv):
'origin': order.name,
'type': 'out_invoice',
'reference': order.client_order_ref or order.name,
'account_id': order.partner_id.property_account_receivable.id,
'account_id': order.partner_invoice_id.property_account_receivable.id,
'partner_id': order.partner_invoice_id.id,
'journal_id': journal_ids[0],
'invoice_line': [(6, 0, lines)],
'currency_id': order.pricelist_id.currency_id.id,
'comment': order.note,
'payment_term': order.payment_term and order.payment_term.id or False,
'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
'fiscal_position': order.fiscal_position.id or order.partner_invoice_id.property_account_position.id,
'date_invoice': context.get('date_invoice', False),
'company_id': order.company_id.id,
'user_id': order.user_id and order.user_id.id or False,
+1 -6
View File
@@ -264,12 +264,7 @@
Click to add a serial number.
</p><p>
This is the list of all the production lots you recorded. When
you select a lot, you can get the
traceability of the products contained in lot. By default, the
list is filtered on the serial numbers that are available in
your warehouse but you can uncheck the 'Available' button to
get all the lots you produced, received or delivered to
customers.
you select a lot, you can get the traceability of the products contained in lot.
</p>
</field>
</record>
-4
View File
@@ -227,10 +227,6 @@ instance.web.parse_value = function (value, descriptor, value_if_empty) {
throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value));
return tmp;
case 'float':
tmp = Number(value);
if (!isNaN(tmp))
return tmp;
var tmp2 = value;
do {
tmp = tmp2;
@@ -11,6 +11,15 @@ instance.web_kanban.SparklineBarWidget = instance.web_kanban.AbstractField.exten
var self = this;
var title = this.$node.html() || this.field.string;
setTimeout(function () {
var tooltipFormatter = function(sp, options, fields) {
var format = $.spformat('<div class="jqsfield">{{offset:offset}} {{formatted_value}}</div>');
var result = '';
$.each(fields, function(i, field) {
field.formatted_value = instance.web.format_value(field.value, { type : 'float' });
result += format.render(field, options.get('tooltipValueLookups'), options);
})
return result;
}
var field_value = JSON.parse(self.field.value);
var value = _.pluck(field_value, 'value');
var tooltips = _.pluck(field_value, 'tooltip');
@@ -24,6 +33,7 @@ instance.web_kanban.SparklineBarWidget = instance.web_kanban.AbstractField.exten
barSpacing: 1,
barColor: '#96d854',
tooltipFormat: tooltipFormat,
tooltipFormatter: self.options.type == 'tristate' ? undefined : tooltipFormatter,
chartRangeMin: 0,
tooltipValueLookups: {
'offset': tooltips
+1 -1
View File
@@ -36,7 +36,7 @@ class sale_quote(http.Controller):
def view(self, order_id, pdf=None, token=None, message=False, **post):
# use SUPERUSER_ID allow to access/view order for public user
# only if he knows the private token
order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id)
order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id, request.context)
now = time.strftime('%Y-%m-%d')
dummy, action = request.registry.get('ir.model.data').get_object_reference(request.cr, request.uid, 'sale', 'action_quotations')
if token:
+1 -1
View File
@@ -4,4 +4,4 @@ Business Mementoes
.. toctree::
Accounting Memento <https://odoo.com/documentation/functional/accounting.html>
Accounting Memento (US GAAP) <https://odoo.com/documentation/functional/accounting.html>
+43
View File
@@ -0,0 +1,43 @@
Brazil, France, 2015-04-14
Akretion France agrees to the terms of the Odoo Corporate Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Sébastien BEAU sebastien.beau@akretion.com https://github.com/akretion
Akretion LTDA agrees to the terms of the Odoo Corporate Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Raphaël Valyi raphael.valyi@akretion.com https://github.com/akretion
List of contributors:
Abdessamad Hilali abdessamad.hilali@akretion.com https://github.com/ahilali
Adrien Chaussende adrien.chaussende@akretion.com https://github.com/achaussende
Alexis de Lattre alexis.delattre@akretion.com https://github.com/alexis-via
Arthur Vuillard arthur.vuillard@akretion.com https://github.com/arthru
Benoît Guillot benoit.guillot@akretion.com https://github.com/bguillot
Chafique delli chafique.delli@akretion.com https://github.com/chafique-delli
Cilene Oliveira cilene.oliveira@akretion.com https://github.com/cileneoliveira
David Beal david.beal@akretion.com https://github.com/bealdav
Florian da Costa florian.dacosta@akretion.com https://github.com/florian-dacosta
Magno Barcelo da Costa magno.costa@akretion.com.br https://github.com/mbcosta
Raphaël Valyi raphael.valyi@akretion.com https://github.com/rvalyi
Renato Lima renato.lima@akretion.com https://github.com/renatonlima
Sebastien Beau sebastien.beau@akretion.com https://github.com/sebastienbeau
Sylvain Calador sylvain.calador@akretion.com https://github.com/sylvainc
Sylvain Legal sylvain.legal@akretion.com https://github.com/legalsylvain
Thiago Moreira de Souza Arrais thiago.moreira@akretion.com.br https://github.com/thiagomds
Valentin Chemiere valentin.chemiere@akretion.com https://github.com/viggor
Vianney da Costa vianney.dacosta@akretion.com.br https://launchpad.net/~vianneydc
+11
View File
@@ -0,0 +1,11 @@
Canada, March 21 2015
I hereby agree to the terms of the Odoo Individual Contributor License
Agreement v1.0.
I declare that I am authorized and able to make this agreement and sign this
declaration.
Signed,
Jean-Nicolas Brunet jnbrunet2000@gmail.com https://github.com/jnbrunet