[MERGE] forward port of branch saas-8 up to 3c7b08c
This commit is contained in:
@@ -1284,7 +1284,7 @@
|
|||||||
<field name="line_ids" widget="one2many_list"
|
<field name="line_ids" widget="one2many_list"
|
||||||
context="{'line_ids': line_ids, 'journal_id': journal_id }">
|
context="{'line_ids': line_ids, 'journal_id': journal_id }">
|
||||||
<tree editable="bottom" string="Journal Items">
|
<tree editable="bottom" string="Journal Items">
|
||||||
<field name="account_id" domain="[('company_id', '=', parent.company_id)]"/>
|
<field name="account_id" domain="[('company_id', '=', parent.company_id), ('deprecated', '=', False)]"/>
|
||||||
<field name="name"/>
|
<field name="name"/>
|
||||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('account_type', '=', 'normal')]"/>
|
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('account_type', '=', 'normal')]"/>
|
||||||
<field name="amount_currency" groups="base.group_multi_currency"/>
|
<field name="amount_currency" groups="base.group_multi_currency"/>
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ class res_users(osv.Model):
|
|||||||
def _auth_oauth_validate(self, cr, uid, provider, access_token, context=None):
|
def _auth_oauth_validate(self, cr, uid, provider, access_token, context=None):
|
||||||
""" return the validation data corresponding to the access token """
|
""" return the validation data corresponding to the access token """
|
||||||
p = self.pool.get('auth.oauth.provider').browse(cr, uid, provider, context=context)
|
p = self.pool.get('auth.oauth.provider').browse(cr, uid, provider, context=context)
|
||||||
validation = self._auth_oauth_rpc(cr, uid, p.validation_endpoint, access_token)
|
validation = self._auth_oauth_rpc(cr, uid, p.validation_endpoint, access_token, context=context)
|
||||||
if validation.get("error"):
|
if validation.get("error"):
|
||||||
raise Exception(validation['error'])
|
raise Exception(validation['error'])
|
||||||
if p.data_endpoint:
|
if p.data_endpoint:
|
||||||
data = self._auth_oauth_rpc(cr, uid, p.data_endpoint, access_token)
|
data = self._auth_oauth_rpc(cr, uid, p.data_endpoint, access_token, context=context)
|
||||||
validation.update(data)
|
validation.update(data)
|
||||||
return validation
|
return validation
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ class res_users(osv.Model):
|
|||||||
# else:
|
# else:
|
||||||
# continue with the process
|
# continue with the process
|
||||||
access_token = params.get('access_token')
|
access_token = params.get('access_token')
|
||||||
validation = self._auth_oauth_validate(cr, uid, provider, access_token)
|
validation = self._auth_oauth_validate(cr, uid, provider, access_token, context=context)
|
||||||
# required check
|
# required check
|
||||||
if not validation.get('user_id'):
|
if not validation.get('user_id'):
|
||||||
# Workaround: facebook does not send 'user_id' in Open Graph Api
|
# Workaround: facebook does not send 'user_id' in Open Graph Api
|
||||||
|
|||||||
@@ -798,6 +798,11 @@ class calendar_event(osv.Model):
|
|||||||
meeting_data[field] = meeting.stop_date if meeting.allday else meeting.stop_datetime
|
meeting_data[field] = meeting.stop_date if meeting.allday else meeting.stop_datetime
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def _get_recurrent_fields(self, cr, uid, context=None):
|
||||||
|
return ['byday', 'recurrency', 'final_date', 'rrule_type', 'month_by',
|
||||||
|
'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa',
|
||||||
|
'su', 'day', 'week_list']
|
||||||
|
|
||||||
def _get_rulestring(self, cr, uid, ids, name, arg, context=None):
|
def _get_rulestring(self, cr, uid, ids, name, arg, context=None):
|
||||||
"""
|
"""
|
||||||
Gets Recurrence rule string according to value type RECUR of iCalendar from the values given.
|
Gets Recurrence rule string according to value type RECUR of iCalendar from the values given.
|
||||||
@@ -808,10 +813,8 @@ class calendar_event(osv.Model):
|
|||||||
ids = [ids]
|
ids = [ids]
|
||||||
|
|
||||||
#read these fields as SUPERUSER because if the record is private a normal search could raise an error
|
#read these fields as SUPERUSER because if the record is private a normal search could raise an error
|
||||||
events = self.read(cr, SUPERUSER_ID, ids,
|
recurrent_fields = self._get_recurrent_fields(cr, uid, context=context)
|
||||||
['id', 'byday', 'recurrency', 'final_date', 'rrule_type', 'month_by',
|
events = self.read(cr, SUPERUSER_ID, ids, recurrent_fields, context=context)
|
||||||
'interval', 'count', 'end_type', 'mo', 'tu', 'we', 'th', 'fr', 'sa',
|
|
||||||
'su', 'day', 'week_list'], context=context)
|
|
||||||
for event in events:
|
for event in events:
|
||||||
if event['recurrency']:
|
if event['recurrency']:
|
||||||
result[event['id']] = self.compute_rule_string(event)
|
result[event['id']] = self.compute_rule_string(event)
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class crm_lead(format_address, osv.osv):
|
|||||||
for lead in self.browse(cr, uid, ids, context=context):
|
for lead in self.browse(cr, uid, ids, context=context):
|
||||||
result[lead.id] = 'grey'
|
result[lead.id] = 'grey'
|
||||||
if lead.date_action:
|
if lead.date_action:
|
||||||
lead_date = datetime.strptime(lead.date_action, tools.DEFAULT_SERVER_DATE_FORMAT)
|
lead_date = datetime.strptime(lead.date_action, tools.DEFAULT_SERVER_DATE_FORMAT).date()
|
||||||
if lead_date > today:
|
if lead_date > today:
|
||||||
result[lead.id] = 'green'
|
result[lead.id] = 'green'
|
||||||
elif lead_date < today:
|
elif lead_date < today:
|
||||||
|
|||||||
@@ -971,9 +971,10 @@ class calendar_event(osv.Model):
|
|||||||
_inherit = "calendar.event"
|
_inherit = "calendar.event"
|
||||||
|
|
||||||
def get_fields_need_update_google(self, cr, uid, context=None):
|
def get_fields_need_update_google(self, cr, uid, context=None):
|
||||||
return ['name', 'description', 'allday', 'start', 'date_end', 'stop',
|
recurrent_fields = self._get_recurrent_fields(cr, uid, context=context)
|
||||||
'attendee_ids', 'alarm_ids', 'location', 'class', 'active',
|
return recurrent_fields + ['name', 'description', 'allday', 'start', 'date_end', 'stop',
|
||||||
'start_date', 'start_datetime', 'stop_date', 'stop_datetime']
|
'attendee_ids', 'alarm_ids', 'location', 'class', 'active',
|
||||||
|
'start_date', 'start_datetime', 'stop_date', 'stop_datetime']
|
||||||
|
|
||||||
def write(self, cr, uid, ids, vals, context=None):
|
def write(self, cr, uid, ids, vals, context=None):
|
||||||
if context is None:
|
if context is None:
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Invite(models.TransientModel):
|
|||||||
if 'message' in fields and model and res_id:
|
if 'message' in fields and model and res_id:
|
||||||
model_name = self.env['ir.model'].search([('model', '=', self.pool[model]._name)]).name_get()[0][1]
|
model_name = self.env['ir.model'].search([('model', '=', self.pool[model]._name)]).name_get()[0][1]
|
||||||
document_name = self.env[model].browse(res_id).name_get()[0][1]
|
document_name = self.env[model].browse(res_id).name_get()[0][1]
|
||||||
message = _('<div><p>Hello,</p><p>%s invited you to follow %s document: %s.<p></div>') % (user_name, model_name, document_name)
|
message = _('<div><p>Hello,</p><p>%s invited you to follow %s document: %s.</p></div>') % (user_name, model_name, document_name)
|
||||||
result['message'] = message
|
result['message'] = message
|
||||||
elif 'message' in fields:
|
elif 'message' in fields:
|
||||||
result['message'] = _('<div><p>Hello,</p><p>%s invited you to follow a new document.</p></div>') % user_name
|
result['message'] = _('<div><p>Hello,</p><p>%s invited you to follow a new document.</p></div>') % user_name
|
||||||
|
|||||||
@@ -87,15 +87,6 @@ your store's efficiency.
|
|||||||
No more hassle of having to integrate softwares: get all your sales and
|
No more hassle of having to integrate softwares: get all your sales and
|
||||||
inventory operations automatically posted in your G/L.
|
inventory operations automatically posted in your G/L.
|
||||||
|
|
||||||
Self-checkout Interface
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Reduce costs by limitting the number of required cashiers. The self-checkout
|
|
||||||
mode allows customers to scan products and pay by themselves with a dedicated
|
|
||||||
and super easy user interface.
|
|
||||||
|
|
||||||
Use lights and sounds to control the checkout distantly.
|
|
||||||
|
|
||||||
Unified Data Amongst All Shops
|
Unified Data Amongst All Shops
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -176,26 +176,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class='oe_container oe_dark'>
|
|
||||||
<div class='oe_row'>
|
|
||||||
<h2 class='oe_slogan'>Self-checkout Interface</h2>
|
|
||||||
<div class='oe_span6'>
|
|
||||||
<p>
|
|
||||||
Reduce costs by limitting the number of required cashiers.
|
|
||||||
The self-checkout mode allows customers to scan products and pay by
|
|
||||||
themselves with a dedicated and super easy user interface.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Use lights and sounds to control the checkout distantly.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class='oe_span6'>
|
|
||||||
<img class="oe_picture oe_screenshot" src="pos_checkout.jpg">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
|
|
||||||
<section class='oe_container'>
|
<section class='oe_container'>
|
||||||
<div class='oe_row'>
|
<div class='oe_row'>
|
||||||
<h2 class='oe_slogan'>Unified Data Amongst All Shops</h2>
|
<h2 class='oe_slogan'>Unified Data Amongst All Shops</h2>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
@@ -90,7 +90,6 @@ class procurement_order(osv.osv):
|
|||||||
_description = "Procurement"
|
_description = "Procurement"
|
||||||
_order = 'priority desc, date_planned, id asc'
|
_order = 'priority desc, date_planned, id asc'
|
||||||
_inherit = ['mail.thread','ir.needaction_mixin']
|
_inherit = ['mail.thread','ir.needaction_mixin']
|
||||||
_log_create = False
|
|
||||||
_columns = {
|
_columns = {
|
||||||
'name': fields.text('Description', required=True),
|
'name': fields.text('Description', required=True),
|
||||||
|
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class PurchaseOrder(models.Model):
|
|||||||
@api.multi
|
@api.multi
|
||||||
def unlink(self):
|
def unlink(self):
|
||||||
for order in self:
|
for order in self:
|
||||||
if order.state not in ['draft', 'cancel']:
|
if not order.state == 'cancel':
|
||||||
raise UserError(_('In order to delete a purchase order, you must cancel it first.'))
|
raise UserError(_('In order to delete a purchase order, you must cancel it first.'))
|
||||||
return super(PurchaseOrder, self).unlink()
|
return super(PurchaseOrder, self).unlink()
|
||||||
|
|
||||||
|
|||||||
@@ -13,15 +13,19 @@
|
|||||||
self.unlink(cr, uid, [ref("purchase_order_1")])
|
self.unlink(cr, uid, [ref("purchase_order_1")])
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
pass
|
pass
|
||||||
|
-
|
||||||
|
I delete a cancelled order.
|
||||||
|
-
|
||||||
|
!python {model: purchase.order}: |
|
||||||
|
from openerp.exceptions import UserError
|
||||||
|
try:
|
||||||
|
self.unlink(cr, uid, [ref("purchase_order_7")])
|
||||||
|
except UserError:
|
||||||
|
pass
|
||||||
-
|
-
|
||||||
I delete a draft order.
|
I delete a draft order.
|
||||||
-
|
-
|
||||||
!python {model: purchase.order}: |
|
!python {model: purchase.order}: |
|
||||||
self.unlink(cr, uid, [ref("purchase_order_5")])
|
self.unlink(cr, uid, [ref("purchase_order_5")])
|
||||||
-
|
|
||||||
I delete a cancelled order.
|
|
||||||
-
|
|
||||||
!python {model: purchase.order}: |
|
|
||||||
self.unlink(cr, uid, [ref("purchase_order_7")])
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -151,7 +151,9 @@ class product_product(osv.osv):
|
|||||||
moves_in = dict(map(lambda x: (x['product_id'][0], x['product_qty']), moves_in))
|
moves_in = dict(map(lambda x: (x['product_id'][0], x['product_qty']), moves_in))
|
||||||
moves_out = dict(map(lambda x: (x['product_id'][0], x['product_qty']), moves_out))
|
moves_out = dict(map(lambda x: (x['product_id'][0], x['product_qty']), moves_out))
|
||||||
res = {}
|
res = {}
|
||||||
for product in self.browse(cr, uid, ids, context=context):
|
ctx = context.copy()
|
||||||
|
ctx.update({'prefetch_fields': False})
|
||||||
|
for product in self.browse(cr, uid, ids, context=ctx):
|
||||||
id = product.id
|
id = product.id
|
||||||
qty_available = float_round(quants.get(id, 0.0), precision_rounding=product.uom_id.rounding)
|
qty_available = float_round(quants.get(id, 0.0), precision_rounding=product.uom_id.rounding)
|
||||||
incoming_qty = float_round(moves_in.get(id, 0.0), precision_rounding=product.uom_id.rounding)
|
incoming_qty = float_round(moves_in.get(id, 0.0), precision_rounding=product.uom_id.rounding)
|
||||||
|
|||||||
@@ -1764,7 +1764,6 @@ class stock_move(osv.osv):
|
|||||||
_name = "stock.move"
|
_name = "stock.move"
|
||||||
_description = "Stock Move"
|
_description = "Stock Move"
|
||||||
_order = 'picking_id, sequence, id'
|
_order = 'picking_id, sequence, id'
|
||||||
_log_create = False
|
|
||||||
|
|
||||||
def get_price_unit(self, cr, uid, move, context=None):
|
def get_price_unit(self, cr, uid, move, context=None):
|
||||||
""" Returns the unit price to store on the quant """
|
""" Returns the unit price to store on the quant """
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
from openerp import models, api
|
from openerp import models, api
|
||||||
|
|
||||||
|
def edit_translation_mapping(data):
|
||||||
|
data = dict(data, model=data['name'].partition(',')[0])
|
||||||
|
return '<span data-oe-model="%(model)s" data-oe-translation-id="%(id)s" data-oe-translation-state="%(state)s">%(value)s</span>' % data
|
||||||
|
|
||||||
class ir_translation(models.Model):
|
class ir_translation(models.Model):
|
||||||
_inherit = 'ir.translation'
|
_inherit = 'ir.translation'
|
||||||
|
|
||||||
@@ -10,5 +14,5 @@ class ir_translation(models.Model):
|
|||||||
def _get_terms_mapping(self, field, records):
|
def _get_terms_mapping(self, field, records):
|
||||||
if self._context.get('edit_translations'):
|
if self._context.get('edit_translations'):
|
||||||
self.insert_missing(field, records)
|
self.insert_missing(field, records)
|
||||||
return lambda data: '<span data-oe-translation-id="%(id)s" data-oe-translation-state="%(state)s">%(value)s</span>' % data
|
return edit_translation_mapping
|
||||||
return super(ir_translation, self)._get_terms_mapping(field, records)
|
return super(ir_translation, self)._get_terms_mapping(field, records)
|
||||||
|
|||||||
@@ -478,7 +478,8 @@ class website(osv.osv):
|
|||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
endpoint = rule.endpoint
|
endpoint = rule.endpoint
|
||||||
methods = rule.methods or ['GET']
|
methods = endpoint.routing.get('method') or ['GET']
|
||||||
|
|
||||||
converters = rule._converters.values()
|
converters = rule._converters.values()
|
||||||
if not ('GET' in methods
|
if not ('GET' in methods
|
||||||
and endpoint.routing['type'] == 'http'
|
and endpoint.routing['type'] == 'http'
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ var base = require('web_editor.base');
|
|||||||
var core = require('web.core');
|
var core = require('web.core');
|
||||||
var _t = core._t;
|
var _t = core._t;
|
||||||
|
|
||||||
var shopping_cart_link = $('ul#top_menu li a[href^="/shop/cart"]');
|
var shopping_cart_link = $('ul#top_menu li a[href$="/shop/cart"]');
|
||||||
var shopping_cart_link_counter;
|
var shopping_cart_link_counter;
|
||||||
shopping_cart_link.popover({
|
shopping_cart_link.popover({
|
||||||
trigger: 'manual',
|
trigger: 'manual',
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ def constrains(*args):
|
|||||||
|
|
||||||
Should raise :class:`~openerp.exceptions.ValidationError` if the
|
Should raise :class:`~openerp.exceptions.ValidationError` if the
|
||||||
validation failed.
|
validation failed.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
``@constrains`` only supports simple field names, dotted names
|
||||||
|
(fields of relational fields e.g. ``partner_id.customer``) are not
|
||||||
|
supported and will be ignored
|
||||||
"""
|
"""
|
||||||
return lambda method: decorate(method, '_constrains', args)
|
return lambda method: decorate(method, '_constrains', args)
|
||||||
|
|
||||||
@@ -165,6 +171,12 @@ def onchange(*args):
|
|||||||
'warning': {'title': "Warning", 'message': "What is this?"},
|
'warning': {'title': "Warning", 'message': "What is this?"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
``@onchange`` only supports simple field names, dotted names
|
||||||
|
(fields of relational fields e.g. ``partner_id.tz``) are not
|
||||||
|
supported and will be ignored
|
||||||
"""
|
"""
|
||||||
return lambda method: decorate(method, '_onchange', args)
|
return lambda method: decorate(method, '_onchange', args)
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -342,7 +342,6 @@ class BaseModel(object):
|
|||||||
_inherit_fields = {}
|
_inherit_fields = {}
|
||||||
|
|
||||||
_table = None
|
_table = None
|
||||||
_log_create = False
|
|
||||||
_sql_constraints = []
|
_sql_constraints = []
|
||||||
|
|
||||||
# model dependencies, for models backed up by sql views:
|
# model dependencies, for models backed up by sql views:
|
||||||
@@ -4367,13 +4366,6 @@ class BaseModel(object):
|
|||||||
# recompute new-style fields
|
# recompute new-style fields
|
||||||
recs.recompute()
|
recs.recompute()
|
||||||
|
|
||||||
if self._log_create and recs.env.recompute and context.get('recompute', True):
|
|
||||||
message = self._description + \
|
|
||||||
" '" + \
|
|
||||||
self.name_get(cr, user, [id_new], context=context)[0][1] + \
|
|
||||||
"' " + _("created.")
|
|
||||||
self.log(cr, user, id_new, message, True, context=context)
|
|
||||||
|
|
||||||
self.check_access_rule(cr, user, [id_new], 'create', context=context)
|
self.check_access_rule(cr, user, [id_new], 'create', context=context)
|
||||||
self.create_workflow(cr, user, [id_new], context=context)
|
self.create_workflow(cr, user, [id_new], context=context)
|
||||||
return id_new
|
return id_new
|
||||||
@@ -4620,11 +4612,24 @@ class BaseModel(object):
|
|||||||
"""
|
"""
|
||||||
lang = self._context.get('lang')
|
lang = self._context.get('lang')
|
||||||
if lang and lang != 'en_US':
|
if lang and lang != 'en_US':
|
||||||
|
# Sub-select to return at most one translation per record.
|
||||||
|
# Even if it shoud probably not be the case,
|
||||||
|
# this is possible to have multiple translations for a same record in the same language.
|
||||||
|
# The parenthesis surrounding the select are important, as this is a sub-select.
|
||||||
|
# The quotes surrounding `ir_translation` are important as well.
|
||||||
|
unique_translation_subselect = """
|
||||||
|
(SELECT DISTINCT ON (res_id) res_id, value
|
||||||
|
FROM "ir_translation"
|
||||||
|
WHERE
|
||||||
|
name = %s AND
|
||||||
|
lang = %s AND
|
||||||
|
value != %s
|
||||||
|
ORDER BY res_id, id DESC)
|
||||||
|
"""
|
||||||
alias, alias_statement = query.add_join(
|
alias, alias_statement = query.add_join(
|
||||||
(table_alias, 'ir_translation', 'id', 'res_id', field),
|
(table_alias, unique_translation_subselect, 'id', 'res_id', field),
|
||||||
implicit=False,
|
implicit=False,
|
||||||
outer=True,
|
outer=True,
|
||||||
extra='"{rhs}"."name" = %s AND "{rhs}"."lang" = %s AND "{rhs}"."value" != %s',
|
|
||||||
extra_params=["%s,%s" % (self._name, field), lang, ""],
|
extra_params=["%s,%s" % (self._name, field), lang, ""],
|
||||||
)
|
)
|
||||||
return 'COALESCE("%s"."%s", "%s"."%s")' % (alias, 'value', table_alias, field)
|
return 'COALESCE("%s"."%s", "%s"."%s")' % (alias, 'value', table_alias, field)
|
||||||
|
|||||||
@@ -132,8 +132,8 @@ class Query(object):
|
|||||||
self.tables.append(alias_statement)
|
self.tables.append(alias_statement)
|
||||||
join_tuple = (alias, lhs_col, col, outer and 'LEFT JOIN' or 'JOIN')
|
join_tuple = (alias, lhs_col, col, outer and 'LEFT JOIN' or 'JOIN')
|
||||||
self.joins.setdefault(lhs, []).append(join_tuple)
|
self.joins.setdefault(lhs, []).append(join_tuple)
|
||||||
if extra:
|
if extra or extra_params:
|
||||||
extra = extra.format(lhs=lhs, rhs=alias)
|
extra = (extra or '').format(lhs=lhs, rhs=alias)
|
||||||
self.extras[(lhs, join_tuple)] = (extra, extra_params)
|
self.extras[(lhs, join_tuple)] = (extra, extra_params)
|
||||||
return alias, alias_statement
|
return alias, alias_statement
|
||||||
|
|
||||||
@@ -152,9 +152,11 @@ class Query(object):
|
|||||||
(join, alias_mapping[rhs], lhs, lhs_col, rhs, rhs_col))
|
(join, alias_mapping[rhs], lhs, lhs_col, rhs, rhs_col))
|
||||||
extra = self.extras.get((lhs, (rhs, lhs_col, rhs_col, join)))
|
extra = self.extras.get((lhs, (rhs, lhs_col, rhs_col, join)))
|
||||||
if extra:
|
if extra:
|
||||||
from_clause.append(' AND ')
|
if extra[0]:
|
||||||
from_clause.append(extra[0])
|
from_clause.append(' AND ')
|
||||||
from_params.extend(extra[1])
|
from_clause.append(extra[0])
|
||||||
|
if extra[1]:
|
||||||
|
from_params.extend(extra[1])
|
||||||
from_clause.append(')')
|
from_clause.append(')')
|
||||||
add_joins_for_table(rhs)
|
add_joins_for_table(rhs)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user