[MERGE] Forward-port of latest saas-1 bugfixes, up to rev. 8781 rev-id: dle@openerp.com-20130923165651-0jt823r5wy37enw6

bzr revid: dle@openerp.com-20130923171310-mav1riq3d2rebmv2
This commit is contained in:
Denis Ledoux 2013-09-23 19:13:10 +02:00
commit db84e912bd
29 changed files with 368 additions and 105 deletions

View File

@ -1416,14 +1416,17 @@ class account_move(osv.osv):
l[2]['period_id'] = default_period l[2]['period_id'] = default_period
context['period_id'] = default_period context['period_id'] = default_period
if 'line_id' in vals: if vals.get('line_id', False):
c = context.copy() c = context.copy()
c['novalidate'] = True c['novalidate'] = True
c['period_id'] = vals['period_id'] if 'period_id' in vals else self._get_period(cr, uid, context) c['period_id'] = vals['period_id'] if 'period_id' in vals else self._get_period(cr, uid, context)
c['journal_id'] = vals['journal_id'] c['journal_id'] = vals['journal_id']
if 'date' in vals: c['date'] = vals['date'] if 'date' in vals: c['date'] = vals['date']
result = super(account_move, self).create(cr, uid, vals, c) result = super(account_move, self).create(cr, uid, vals, c)
self.validate(cr, uid, [result], context) tmp = self.validate(cr, uid, [result], context)
journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context)
if journal.entry_posted and tmp:
self.button_validate(cr,uid, [result], context)
else: else:
result = super(account_move, self).create(cr, uid, vals, context) result = super(account_move, self).create(cr, uid, vals, context)
return result return result

View File

@ -349,6 +349,7 @@
<page string="Invoice Lines"> <page string="Invoice Lines">
<field name="invoice_line" nolabel="1" widget="one2many_list" context="{'type': type}"> <field name="invoice_line" nolabel="1" widget="one2many_list" context="{'type': type}">
<tree string="Invoice Lines" editable="bottom"> <tree string="Invoice Lines" editable="bottom">
<field name="sequence" widget="handle"/>
<field name="product_id" <field name="product_id"
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/> on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="name"/> <field name="name"/>

View File

@ -1283,7 +1283,7 @@ class account_move_line(osv.osv):
self.create(cr, uid, data, context) self.create(cr, uid, data, context)
del vals['account_tax_id'] del vals['account_tax_id']
if check and ((not context.get('no_store_function')) or journal.entry_posted): if check and not context.get('novalidate') and ((not context.get('no_store_function')) or journal.entry_posted):
tmp = move_obj.validate(cr, uid, [vals['move_id']], context) tmp = move_obj.validate(cr, uid, [vals['move_id']], context)
if journal.entry_posted and tmp: if journal.entry_posted and tmp:
move_obj.button_validate(cr,uid, [vals['move_id']], context) move_obj.button_validate(cr,uid, [vals['move_id']], context)

View File

@ -15,7 +15,7 @@
<newline/> <newline/>
</xpath> </xpath>
<xpath expr="//field[@name='filter']" position="replace"> <xpath expr="//field[@name='filter']" position="replace">
<field name="filter" on_change="onchange_filter(filter, fiscalyear_id)" colspan="4"/> <field name="filter" on_change="onchange_filter(filter, fiscalyear_id)"/>
<field name="initial_balance" attrs="{'readonly':[('filter', 'in', ('filter_no', 'unreconciled'))]}" /> <field name="initial_balance" attrs="{'readonly':[('filter', 'in', ('filter_no', 'unreconciled'))]}" />
</xpath> </xpath>
</data> </data>

View File

@ -1208,20 +1208,44 @@ rule or repeating pattern of time to exclude from the recurring rule."),
new_rrule_str = ';'.join(new_rrule_str) new_rrule_str = ';'.join(new_rrule_str)
rdates = get_recurrent_dates(str(new_rrule_str), exdate, event_date, data['exrule']) rdates = get_recurrent_dates(str(new_rrule_str), exdate, event_date, data['exrule'])
for r_date in rdates: for r_date in rdates:
ok = True # fix domain evaluation
# step 1: check date and replace expression by True or False, replace other expressions by True
# step 2: evaluation of & and |
# check if there are one False
pile = []
for arg in domain: for arg in domain:
if arg[0] in ('date', 'date_deadline'): if str(arg[0]) in (str('date'), str('date_deadline')):
if (arg[1]=='='): if (arg[1] == '='):
ok = ok and r_date.strftime('%Y-%m-%d')==arg[2] ok = r_date.strftime('%Y-%m-%d')==arg[2]
if (arg[1]=='>'): if (arg[1] == '>'):
ok = ok and r_date.strftime('%Y-%m-%d')>arg[2] ok = r_date.strftime('%Y-%m-%d')>arg[2]
if (arg[1]=='<'): if (arg[1] == '<'):
ok = ok and r_date.strftime('%Y-%m-%d')<arg[2] ok = r_date.strftime('%Y-%m-%d')<arg[2]
if (arg[1]=='>='): if (arg[1] == '>='):
ok = ok and r_date.strftime('%Y-%m-%d')>=arg[2] ok = r_date.strftime('%Y-%m-%d')>=arg[2]
if (arg[1]=='<='): if (arg[1] == '<='):
ok = ok and r_date.strftime('%Y-%m-%d')<=arg[2] ok = r_date.strftime('%Y-%m-%d')<=arg[2]
if not ok: pile.append(ok)
elif str(arg) == str('&') or str(arg) == str('|'):
pile.append(arg)
else:
pile.append(True)
pile.reverse()
new_pile = []
for item in pile:
if not isinstance(item, basestring):
res = item
elif str(item) == str('&'):
first = new_pile.pop()
second = new_pile.pop()
res = first and second
elif str(item) == str('|'):
first = new_pile.pop()
second = new_pile.pop()
res = first or second
new_pile.append(res)
if [True for item in new_pile if not item]:
continue continue
idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S")) idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S"))
result.append(idval) result.append(idval)
@ -1346,18 +1370,17 @@ rule or repeating pattern of time to exclude from the recurring rule."),
for arg in args: for arg in args:
new_arg = arg new_arg = arg
if arg[0] in ('date', unicode('date'), 'date_deadline', unicode('date_deadline')): if arg[0] in ('date_deadline', unicode('date_deadline')):
if context.get('virtual_id', True): if context.get('virtual_id', True):
new_args += ['|','&',('recurrency','=',1),('recurrent_id_date', arg[1], arg[2])] new_args += ['|','&',('recurrency','=',1),('end_date', arg[1], arg[2])]
elif arg[0] == "id": elif arg[0] == "id":
new_id = get_real_ids(arg[2]) new_id = get_real_ids(arg[2])
new_arg = (arg[0], arg[1], new_id) new_arg = (arg[0], arg[1], new_id)
new_args.append(new_arg) new_args.append(new_arg)
#offset, limit and count must be treated separately as we may need to deal with virtual ids #offset, limit and count must be treated separately as we may need to deal with virtual ids
res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False) res = super(calendar_event, self).search(cr, uid, new_args, offset=0, limit=0, order=order, context=context, count=False)
if context.get('virtual_id', True): if context.get('virtual_id', True):
res = self.get_recurrent_ids(cr, uid, res, new_args, limit, context=context) res = self.get_recurrent_ids(cr, uid, res, args, limit, context=context)
if count: if count:
return len(res) return len(res)
elif limit: elif limit:
@ -1436,6 +1459,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
vals['vtimezone'] = vals['vtimezone'][40:] vals['vtimezone'] = vals['vtimezone'][40:]
res = super(calendar_event, self).write(cr, uid, ids, vals, context=context) res = super(calendar_event, self).write(cr, uid, ids, vals, context=context)
# set end_date for calendar searching
if vals.get('recurrency', True) and vals.get('end_type', 'count') in ('count', unicode('count')) and \
(vals.get('rrule_type') or vals.get('count') or vals.get('date') or vals.get('date_deadline')):
for data in self.read(cr, uid, ids, ['date', 'date_deadline', 'recurrency', 'rrule_type', 'count', 'end_type'], context=context):
end_date = self._set_recurrency_end_date(data, context=context)
super(calendar_event, self).write(cr, uid, [data['id']], {'end_date': end_date}, context=context)
if vals.get('partner_ids', False): if vals.get('partner_ids', False):
self.create_attendees(cr, uid, ids, context) self.create_attendees(cr, uid, ids, context)
@ -1554,6 +1585,21 @@ rule or repeating pattern of time to exclude from the recurring rule."),
self.unlink_events(cr, uid, ids, context=context) self.unlink_events(cr, uid, ids, context=context)
return res return res
def _set_recurrency_end_date(self, data, context=None):
end_date = data.get('end_date')
if data.get('recurrency') and data.get('end_type') in ('count', unicode('count')):
data_date_deadline = datetime.strptime(data.get('date_deadline'), '%Y-%m-%d %H:%M:%S')
if data.get('rrule_type') in ('daily', unicode('count')):
rel_date = relativedelta(days=data.get('count')+1)
elif data.get('rrule_type') in ('weekly', unicode('weekly')):
rel_date = relativedelta(days=(data.get('count')+1)*7)
elif data.get('rrule_type') in ('monthly', unicode('monthly')):
rel_date = relativedelta(months=data.get('count')+1)
elif data.get('rrule_type') in ('yearly', unicode('yearly')):
rel_date = relativedelta(years=data.get('count')+1)
end_date = data_date_deadline + rel_date
return end_date
def create(self, cr, uid, vals, context=None): def create(self, cr, uid, vals, context=None):
if context is None: if context is None:
context = {} context = {}
@ -1561,7 +1607,9 @@ rule or repeating pattern of time to exclude from the recurring rule."),
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'): if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
vals['vtimezone'] = vals['vtimezone'][40:] vals['vtimezone'] = vals['vtimezone'][40:]
vals['end_date'] = self._set_recurrency_end_date(vals, context=context)
res = super(calendar_event, self).create(cr, uid, vals, context) res = super(calendar_event, self).create(cr, uid, vals, context)
alarm_obj = self.pool.get('res.alarm') alarm_obj = self.pool.get('res.alarm')
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context) alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
self.create_attendees(cr, uid, [res], context) self.create_attendees(cr, uid, [res], context)

View File

@ -458,7 +458,7 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
THEN (SUM(total_attendance) + THEN (SUM(total_attendance) +
CASE WHEN current_date <> name CASE WHEN current_date <> name
THEN 1440 THEN 1440
ELSE (EXTRACT(hour FROM current_time) * 60) + EXTRACT(minute FROM current_time) ELSE (EXTRACT(hour FROM current_time AT TIME ZONE 'UTC') * 60) + EXTRACT(minute FROM current_time AT TIME ZONE 'UTC')
END END
) )
ELSE SUM(total_attendance) ELSE SUM(total_attendance)

View File

@ -77,6 +77,7 @@ Dashboard / Reports for MRP will include:
#TODO: This yml tests are needed to be completely reviewed again because the product wood panel is removed in product demo as it does not suit for new demo context of computer and consultant company #TODO: This yml tests are needed to be completely reviewed again because the product wood panel is removed in product demo as it does not suit for new demo context of computer and consultant company
# so the ymls are too complex to change at this stage # so the ymls are too complex to change at this stage
'test': [ 'test': [
'test/bom_with_service_type_product.yml',
'test/mrp_users.yml', 'test/mrp_users.yml',
'test/order_demo.yml', 'test/order_demo.yml',
'test/order_process.yml', 'test/order_process.yml',

View File

@ -602,11 +602,11 @@ class mrp_production(osv.osv):
self.write(cr, uid, ids, {'state': 'picking_except'}) self.write(cr, uid, ids, {'state': 'picking_except'})
return True return True
def action_compute(self, cr, uid, ids, properties=None, context=None): def _action_compute_lines(self, cr, uid, ids, properties=None, context=None):
""" Computes bills of material of a product. """ Compute product_lines and workcenter_lines from BoM structure
@param properties: List containing dictionaries of properties. @return: product_lines
@return: No. of products.
""" """
if properties is None: if properties is None:
properties = [] properties = []
results = [] results = []
@ -614,13 +614,15 @@ class mrp_production(osv.osv):
uom_obj = self.pool.get('product.uom') uom_obj = self.pool.get('product.uom')
prod_line_obj = self.pool.get('mrp.production.product.line') prod_line_obj = self.pool.get('mrp.production.product.line')
workcenter_line_obj = self.pool.get('mrp.production.workcenter.line') workcenter_line_obj = self.pool.get('mrp.production.workcenter.line')
for production in self.browse(cr, uid, ids):
p_ids = prod_line_obj.search(cr, SUPERUSER_ID, [('production_id', '=', production.id)], context=context) for production in self.browse(cr, uid, ids, context=context):
prod_line_obj.unlink(cr, SUPERUSER_ID, p_ids, context=context) #unlink product_lines
w_ids = workcenter_line_obj.search(cr, SUPERUSER_ID, [('production_id', '=', production.id)], context=context) prod_line_obj.unlink(cr, SUPERUSER_ID, [line.id for line in production.product_lines], context=context)
workcenter_line_obj.unlink(cr, SUPERUSER_ID, w_ids, context=context)
#unlink workcenter_lines
workcenter_line_obj.unlink(cr, SUPERUSER_ID, [line.id for line in production.workcenter_lines], context=context)
# search BoM structure and route
bom_point = production.bom_id bom_point = production.bom_id
bom_id = production.bom_id.id bom_id = production.bom_id.id
if not bom_point: if not bom_point:
@ -632,17 +634,30 @@ class mrp_production(osv.osv):
if not bom_id: if not bom_id:
raise osv.except_osv(_('Error!'), _("Cannot find a bill of material for this product.")) raise osv.except_osv(_('Error!'), _("Cannot find a bill of material for this product."))
# get components and workcenter_lines from BoM structure
factor = uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, bom_point.product_uom.id) factor = uom_obj._compute_qty(cr, uid, production.product_uom.id, production.product_qty, bom_point.product_uom.id)
res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id) res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id)
results = res[0] results = res[0] # product_lines
results2 = res[1] results2 = res[1] # workcenter_lines
# reset product_lines in production order
for line in results: for line in results:
line['production_id'] = production.id line['production_id'] = production.id
prod_line_obj.create(cr, uid, line) prod_line_obj.create(cr, uid, line)
#reset workcenter_lines in production order
for line in results2: for line in results2:
line['production_id'] = production.id line['production_id'] = production.id
workcenter_line_obj.create(cr, uid, line) workcenter_line_obj.create(cr, uid, line)
return len(results) return results
def action_compute(self, cr, uid, ids, properties=None, context=None):
""" Computes bills of material of a product.
@param properties: List containing dictionaries of properties.
@return: No. of products.
"""
return len(self._action_compute_lines(cr, uid, ids, properties=properties, context=context))
def action_cancel(self, cr, uid, ids, context=None): def action_cancel(self, cr, uid, ids, context=None):
""" Cancels the production order and related stock moves. """ Cancels the production order and related stock moves.
@ -669,8 +684,12 @@ class mrp_production(osv.osv):
move_obj = self.pool.get('stock.move') move_obj = self.pool.get('stock.move')
self.write(cr, uid, ids, {'state': 'ready'}) self.write(cr, uid, ids, {'state': 'ready'})
for (production_id,name) in self.name_get(cr, uid, ids): for production in self.browse(cr, uid, ids, context=context):
production = self.browse(cr, uid, production_id) if not production.move_created_ids:
produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)
for scheduled in production.product_lines:
self._make_production_line_procurement(cr, uid, scheduled, False, context=context)
if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id: if production.move_prod_id and production.move_prod_id.location_id.id != production.location_dest_id.id:
move_obj.write(cr, uid, [production.move_prod_id.id], move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id': production.location_dest_id.id}) {'location_id': production.location_dest_id.id})
@ -722,6 +741,10 @@ class mrp_production(osv.osv):
stock_mov_obj = self.pool.get('stock.move') stock_mov_obj = self.pool.get('stock.move')
production = self.browse(cr, uid, production_id, context=context) production = self.browse(cr, uid, production_id, context=context)
if not production.move_lines and production.state == 'ready':
# trigger workflow if not products to consume (eg: services)
self.signal_button_produce(cr, uid, [production_id])
produced_qty = 0 produced_qty = 0
for produced_product in production.move_created_ids2: for produced_product in production.move_created_ids2:
if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id): if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id):
@ -784,9 +807,9 @@ class mrp_production(osv.osv):
subproduct_factor = self._get_subproduct_factor(cr, uid, production.id, produce_product.id, context=context) subproduct_factor = self._get_subproduct_factor(cr, uid, production.id, produce_product.id, context=context)
rest_qty = (subproduct_factor * production.product_qty) - produced_qty rest_qty = (subproduct_factor * production.product_qty) - produced_qty
if rest_qty < production_qty: if rest_qty < (subproduct_factor * production_qty):
prod_name = produce_product.product_id.name_get()[0][1] prod_name = produce_product.product_id.name_get()[0][1]
raise osv.except_osv(_('Warning!'), _('You are going to produce total %s quantities of "%s".\nBut you can only produce up to total %s quantities.') % (production_qty, prod_name, rest_qty)) raise osv.except_osv(_('Warning!'), _('You are going to produce total %s quantities of "%s".\nBut you can only produce up to total %s quantities.') % ((subproduct_factor * production_qty), prod_name, rest_qty))
if rest_qty > 0 : if rest_qty > 0 :
stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), context=context) stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), context=context)
@ -861,14 +884,20 @@ class mrp_production(osv.osv):
""" """
res = True res = True
for production in self.browse(cr, uid, ids): for production in self.browse(cr, uid, ids):
if not production.product_lines: boms = self._action_compute_lines(cr, uid, [production.id])
if not self.action_compute(cr, uid, [production.id]):
res = False res = False
for bom in boms:
product = self.pool.get('product.product').browse(cr, uid, bom['product_id'])
if product.type in ('product', 'consu'):
res = True
return res return res
def _get_auto_picking(self, cr, uid, production): def _get_auto_picking(self, cr, uid, production):
return True return True
def _hook_create_post_procurement(self, cr, uid, production, procurement_id, context=None):
return True
def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None): def _make_production_line_procurement(self, cr, uid, production_line, shipment_move_id, context=None):
procurement_order = self.pool.get('procurement.order') procurement_order = self.pool.get('procurement.order')
production = production_line.production_id production = production_line.production_id
@ -1015,10 +1044,12 @@ class mrp_production(osv.osv):
for line in production.product_lines: for line in production.product_lines:
consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context) consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
if shipment_id:
shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\ shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
destination_location_id=source_location_id, context=context) destination_location_id=source_location_id, context=context)
self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context) self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)
if shipment_id:
self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id]) self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id])
production.write({'state':'confirmed'}, context=context) production.write({'state':'confirmed'}, context=context)
return shipment_id return shipment_id

View File

@ -0,0 +1,134 @@
-
I create Bill of Materials with one service type product and one consumable product.
-
!record {model: mrp.bom, id: mrp_bom_test1}:
company_id: base.main_company
name: PC Assemble SC234
product_id: product.product_product_3
product_qty: 1.0
type: normal
bom_lines:
- company_id: base.main_company
name: On Site Assistance
product_id: product.product_product_2
product_qty: 1.0
- company_id: base.main_company
name: GrapWorks Software
product_id: product.product_product_44
product_qty: 1.0
-
I make the production order using BoM having one service type product and one consumable product.
-
!record {model: mrp.production, id: mrp_production_servicetype_mo1}:
product_id: product.product_product_5
product_qty: 1.0
bom_id: mrp_bom_test1
date_planned: !eval time.strftime('%Y-%m-%d %H:%M:%S')
-
I compute the data of production order.
-
!python {model: mrp.production}: |
self.action_compute(cr, uid, [ref("mrp_production_servicetype_mo1")], {"lang": "en_US", "tz": False, "search_default_Current": 1,
"active_model": "ir.ui.menu", "active_ids": [ref("mrp.menu_mrp_production_action")],
"active_id": ref("mrp.menu_mrp_production_action"), })
-
I confirm the production order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_servicetype_mo1}
-
I confirm the Consume Products.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1"))
assert order.state == 'confirmed', "Production order should be confirmed."
for move_line in order.move_lines:
move_line.action_consume(move_line.product_qty)
-
I processed the Product Entirely.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1"))
assert order.state == 'in_production', 'Production order should be in production State.'
for move_created in order.move_created_ids:
move_created.action_done()
-
I produce product.
-
!python {model: mrp.product.produce}: |
context.update({'active_id': ref('mrp_production_servicetype_mo1')})
-
!record {model: mrp.product.produce, id: mrp_product_produce_1}:
mode: 'consume_produce'
-
!python {model: mrp.product.produce}: |
self.do_produce(cr, uid, [ref('mrp_product_produce_1')], context=context)
-
I check production order after produced.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_servicetype_mo1"))
assert order.state == 'done', "Production order should be closed."
-
I create Bill of Materials with two service type products.
-
!record {model: mrp.bom, id: mrp_bom_test_2}:
company_id: base.main_company
name: PC Assemble SC234
product_id: product.product_product_3
product_qty: 1.0
type: normal
bom_lines:
- company_id: base.main_company
name: On Site Monitoring
product_id: product.product_product_1
product_qty: 1.0
- company_id: base.main_company
name: On Site Assistance
product_id: product.product_product_2
product_qty: 1.0
-
I make the production order using BoM having two service type products.
-
!record {model: mrp.production, id: mrp_production_servicetype_2}:
product_id: product.product_product_5
product_qty: 1.0
bom_id: mrp_bom_test_2
date_planned: !eval time.strftime('%Y-%m-%d %H:%M:%S')
-
I compute the data of production order.
-
!python {model: mrp.production}: |
self.action_compute(cr, uid, [ref("mrp_production_servicetype_2")], {"lang": "en_US", "tz": False, "search_default_Current": 1,
"active_model": "ir.ui.menu", "active_ids": [ref("mrp.menu_mrp_production_action")],
"active_id": ref("mrp.menu_mrp_production_action"), })
-
I confirm the production order.
-
!workflow {model: mrp.production, action: button_confirm, ref: mrp_production_servicetype_2}
-
Now I start production.
-
!workflow {model: mrp.production, action: button_produce, ref: mrp_production_servicetype_2}
-
I check that production order in production state after start production.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_servicetype_2"))
assert order.state == 'in_production', 'Production order should be in production State.'
-
I produce product.
-
!python {model: mrp.product.produce}: |
context.update({'active_id': ref('mrp_production_servicetype_2')})
-
!record {model: mrp.product.produce, id: mrp_product_produce_2}:
mode: 'consume_produce'
-
!python {model: mrp.product.produce}: |
self.do_produce(cr, uid, [ref('mrp_product_produce_2')], context=context)
-
I check production order after produced.
-
!python {model: mrp.production}: |
order = self.browse(cr, uid, ref("mrp_production_servicetype_2"))
assert order.state == 'done', "Production order should be closed."

View File

@ -9,7 +9,7 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='workcenter_lines']/form//field[@name='name']" position="before"> <xpath expr="//field[@name='workcenter_lines']/form//field[@name='name']" position="before">
<header colspan="8"> <header colspan="8">
<button name="button_start_working" string="Start" states="draft" icon="terp-gtk-jump-to-ltr" help="Start Working"/> <button name="button_start_working" string="Start" states="draft" icon="gtk-media-play" help="Start Working"/>
<button name="button_cancel" string="Cancel Order" states="draft,startworking" icon="gtk-stop" help="Cancel Order"/> <button name="button_cancel" string="Cancel Order" states="draft,startworking" icon="gtk-stop" help="Cancel Order"/>
<button name="button_draft" string="Set Draft" states="cancel" icon="gtk-convert" help="Set to Draft"/> <button name="button_draft" string="Set Draft" states="cancel" icon="gtk-convert" help="Set to Draft"/>
<button name="button_resume" string="Resume" states="pause" icon="gtk-media-pause" help="Resume Work Order"/> <button name="button_resume" string="Resume" states="pause" icon="gtk-media-pause" help="Resume Work Order"/>
@ -29,7 +29,7 @@
<xpath expr="//field[@name='workcenter_lines']/tree/field[@name='hour']" position="after"> <xpath expr="//field[@name='workcenter_lines']/tree/field[@name='hour']" position="after">
<field name="state"/> <field name="state"/>
<button name="button_draft" string="Set Draft" states="cancel" icon="gtk-convert"/> <button name="button_draft" string="Set Draft" states="cancel" icon="gtk-convert"/>
<button name="button_start_working" string="Start" states="draft" icon="terp-gtk-jump-to-ltr"/> <button name="button_start_working" string="Start" states="draft" icon="gtk-media-play"/>
<button name="button_resume" string="Resume" states="pause" icon="gtk-media-pause"/> <button name="button_resume" string="Resume" states="pause" icon="gtk-media-pause"/>
<button name="button_pause" string="Pending" states="startworking" icon="gtk-media-pause"/> <button name="button_pause" string="Pending" states="startworking" icon="gtk-media-pause"/>
<button name="button_done" string="Finished" states="startworking" icon="terp-check"/> <button name="button_done" string="Finished" states="startworking" icon="terp-check"/>

View File

@ -377,20 +377,6 @@ namespace OpenERPClient
return version; return version;
} }
public bool check_connectivity()
{
/*
It will check connection on given server url.
:return : True or False.
*/
this.Open(OpenERPClient.OpenERPService.Common);
bool flag = this.rpcclient.check_connectivity();
this.Close();
return flag;
}
} }

View File

@ -47,10 +47,6 @@ namespace OpenERPClient
[XmlRpcMethod("server_version")] [XmlRpcMethod("server_version")]
string ServerVersion(); string ServerVersion();
[XmlRpcMethod("check_connectivity")]
bool check_connectivity();
} }
public interface Ixmlrpcconnect : IOpenERPCommon, IOpenERPDB, IOpenERPObject public interface Ixmlrpcconnect : IOpenERPCommon, IOpenERPDB, IOpenERPObject
{ {
@ -84,11 +80,6 @@ namespace OpenERPClient
{ {
return rpcclient.ServerVersion(); return rpcclient.ServerVersion();
} }
public bool check_connectivity()
{
return rpcclient.check_connectivity();
}
#endregion #endregion

View File

@ -64,6 +64,7 @@
this.chkSSL.TabIndex = 19; this.chkSSL.TabIndex = 19;
this.chkSSL.Text = "SSL (https)"; this.chkSSL.Text = "SSL (https)";
this.chkSSL.UseVisualStyleBackColor = true; this.chkSSL.UseVisualStyleBackColor = true;
this.chkSSL.CheckedChanged += new System.EventHandler(this.chkSSL_CheckedChanged);
// //
// txt_server_port // txt_server_port
// //

View File

@ -20,6 +20,13 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
using OpenERPClient; using OpenERPClient;
using System.Net;
using System.IO;
using System.Text;
using System.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
namespace OpenERPOutlookPlugin namespace OpenERPOutlookPlugin
{ {
@ -50,6 +57,15 @@ namespace OpenERPOutlookPlugin
} }
} }
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
// Somehow the cert always has PolicyErrors so I am returning true regardless.
return true;
}
private void btn_server_ok_Click(object sender, EventArgs e) private void btn_server_ok_Click(object sender, EventArgs e)
{ {
@ -59,7 +75,10 @@ namespace OpenERPOutlookPlugin
OpenERPConnect openerp_connect = openerp_outlook.Connection; OpenERPConnect openerp_connect = openerp_outlook.Connection;
string url = Tools.JoinURL(this.txt_server_host.Text, this.txt_server_port.Text, this.chkSSL.Checked); string url = Tools.JoinURL(this.txt_server_host.Text, this.txt_server_port.Text, this.chkSSL.Checked);
this.txtServerURL.Text = url; this.txtServerURL.Text = url;
openerp_connect.check_connectivity(); if (this.chkSSL.Checked)
{
ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);
}
this.Close(); this.Close();
} }
catch (Exception ex) catch (Exception ex)
@ -74,6 +93,16 @@ namespace OpenERPOutlookPlugin
this.Close(); this.Close();
} }
private void chkSSL_CheckedChanged(object sender, EventArgs e)
{
if (this.chkSSL.Checked)
{
txt_server_port.Text = "443";
}
else
{
txt_server_port.Text = "8069";
}
}
} }
} }

View File

@ -171,9 +171,7 @@ class product_pricelist(osv.osv):
if context is None: if context is None:
context = {} context = {}
date = time.strftime('%Y-%m-%d') date = context.get('date') or time.strftime('%Y-%m-%d')
if 'date' in context:
date = context['date']
currency_obj = self.pool.get('res.currency') currency_obj = self.pool.get('res.currency')
product_obj = self.pool.get('product.product') product_obj = self.pool.get('product.product')

View File

@ -128,7 +128,7 @@
<notebook> <notebook>
<page string="Team" name="team"> <page string="Team" name="team">
<field colspan="4" name="members" widget="many2many_kanban" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'group_project_user']}"> <field colspan="4" name="members" widget="many2many_kanban" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'group_project_user']}">
<kanban quick_create="false" create="true"> <kanban quick_create="false" create="true" delete="true">
<field name="name"/> <field name="name"/>
<templates> <templates>
<t t-name="kanban-box"> <t t-name="kanban-box">

View File

@ -46,12 +46,29 @@
Process Transition Process Transition
--> -->
<!-- This "foreign" process node is duplicated here from the corresponding sale_stock node because
`project_mrp` implements a basic procurement system for services without actually using the
full-fledged procurement process from sale_stock, and without the dependency. So it stil
represents a "procurement system".
TODO: To cleanup this invalid foreign external ID, the node should probably be moved to the
`sale` module directly, and removed from both `sale_stock` and `project_mrp`.
-->
<record id="sale_stock.process_node_saleprocurement0" model="process.node">
<field name="menu_id" ref="procurement.menu_stock_procurement_action"/>
<field name="model_id" ref="procurement.model_procurement_order"/>
<field name="kind">subflow</field>
<field name="name">Procurement</field>
<field name="subflow_id" ref="procurement.process_process_procurementprocess0"/>
<field name="process_id" ref="sale.process_process_salesprocess0"/>
<field name="model_states">object.state=='confirmed'</field>
<field name="flow_start" eval="1"/>
</record>
<record id="process_transition_procuretask0" model="process.transition"> <record id="process_transition_procuretask0" model="process.transition">
<field eval="[(6,0,[])]" name="transition_ids"/> <field eval="[(6,0,[])]" name="transition_ids"/>
<field eval="&quot;&quot;&quot;Procurement Task&quot;&quot;&quot;" name="name"/> <field eval="&quot;&quot;&quot;Procurement Task&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;if product type is 'service' then it creates the task.&quot;&quot;&quot;" name="note"/> <field eval="&quot;&quot;&quot;if product type is 'service' then it creates the task.&quot;&quot;&quot;" name="note"/>
<field name="target_node_id" ref="process_node_procuretasktask0"/> <field name="target_node_id" ref="process_node_procuretasktask0"/>
<field name="source_node_id" ref="mrp.process_node_productionorder0"/> <field name="source_node_id" ref="sale_stock.process_node_saleprocurement0"/>
</record> </record>
<record id="process_transition_createtask0" model="process.transition"> <record id="process_transition_createtask0" model="process.transition">

View File

@ -125,4 +125,3 @@ class sale_order(osv.osv):
'picked_rate': fields.function(_picked_rate, method=True, string='Picked', type='float'), 'picked_rate': fields.function(_picked_rate, method=True, string='Picked', type='float'),
} }
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1238,8 +1238,8 @@ class account_invoice(osv.Model):
res = super(account_invoice, self).invoice_validate(cr, uid, ids, context=context) res = super(account_invoice, self).invoice_validate(cr, uid, ids, context=context)
purchase_order_obj = self.pool.get('purchase.order') purchase_order_obj = self.pool.get('purchase.order')
po_ids = purchase_order_obj.search(cr, uid, [('invoice_ids', 'in', ids)], context=context) po_ids = purchase_order_obj.search(cr, uid, [('invoice_ids', 'in', ids)], context=context)
if po_ids: for po_id in po_ids:
purchase_order_obj.message_post(cr, uid, po_ids, body=_("Invoice received"), context=context) purchase_order_obj.message_post(cr, uid, po_id, body=_("Invoice received"), context=context)
return res return res
def confirm_paid(self, cr, uid, ids, context=None): def confirm_paid(self, cr, uid, ids, context=None):

View File

@ -43,6 +43,7 @@ class sale_order(osv.osv):
if not default: if not default:
default = {} default = {}
default.update({ default.update({
'date_order': fields.date.context_today(self, cr, uid, context=context),
'state': 'draft', 'state': 'draft',
'invoice_ids': [], 'invoice_ids': [],
'date_confirm': False, 'date_confirm': False,

View File

@ -31,7 +31,7 @@ class sale_order(osv.osv):
_columns = { _columns = {
'section_id': fields.many2one('crm.case.section', 'Sales Team'), 'section_id': fields.many2one('crm.case.section', 'Sales Team'),
'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Categories', \ 'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Categories', \
domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]") domain="['|',('section_id','=',section_id),('section_id','=',False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}")
} }
def _prepare_invoice(self, cr, uid, order, lines, context=None): def _prepare_invoice(self, cr, uid, order, lines, context=None):

View File

@ -69,6 +69,19 @@ class mrp_production(osv.osv):
res[production.id] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False res[production.id] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
return res return res
def _hook_create_post_procurement(self, cr, uid, production, procurement_id, context=None):
def get_parent_move(move):
if move.move_dest_id:
return get_parent_move(move.move_dest_id)
return move
res = super(mrp_production, self)._hook_create_post_procurement(cr, uid, production, procurement_id, context)
if production.move_prod_id:
parent_move_line = get_parent_move(production.move_prod_id)
if parent_move_line and parent_move_line.sale_line_id:
self.pool.get('procurement.order').write(cr, uid, procurement_id, {'sale_line_id': parent_move_line.sale_line_id.id})
return res
_columns = { _columns = {
'sale_name': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sales order.'), 'sale_name': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Name', help='Indicate the name of sales order.'),
'sale_ref': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Reference', help='Indicate the Customer Reference from sales order.'), 'sale_ref': fields.function(_ref_calc, multi='sale_name', type='char', string='Sale Reference', help='Indicate the Customer Reference from sales order.'),

View File

@ -397,7 +397,16 @@ class stock_location(osv.osv):
uom_rounding = self.pool.get('product.product').browse(cr, uid, product_id, context=context).uom_id.rounding uom_rounding = self.pool.get('product.product').browse(cr, uid, product_id, context=context).uom_id.rounding
if context.get('uom'): if context.get('uom'):
uom_rounding = uom_obj.browse(cr, uid, context.get('uom'), context=context).rounding uom_rounding = uom_obj.browse(cr, uid, context.get('uom'), context=context).rounding
for id in self.search(cr, uid, [('location_id', 'child_of', ids)]):
locations_ids = self.search(cr, uid, [('location_id', 'child_of', ids)])
# Fetch only the locations in which this product has ever been processed (in or out)
cr.execute("""SELECT l.id FROM stock_location l WHERE l.id in %s AND
EXISTS (SELECT 1 FROM stock_move m WHERE m.product_id = %s
AND ((state = 'done' AND m.location_dest_id = l.id)
OR (state in ('done','assigned') AND m.location_id = l.id)))
""", (tuple(locations_ids), product_id,))
for id in [i for (i,) in cr.fetchall()]:
if lock: if lock:
try: try:
# Must lock with a separate select query because FOR UPDATE can't be used with # Must lock with a separate select query because FOR UPDATE can't be used with
@ -1910,7 +1919,8 @@ class stock_move(osv.osv):
""" """
if not prod_id: if not prod_id:
return {} return {}
lang = False user = self.pool.get('res.users').browse(cr, uid, uid)
lang = user and user.lang or False
if partner_id: if partner_id:
addr_rec = self.pool.get('res.partner').browse(cr, uid, partner_id) addr_rec = self.pool.get('res.partner').browse(cr, uid, partner_id)
if addr_rec: if addr_rec:

View File

@ -759,7 +759,7 @@
<header> <header>
<button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight" groups="base.group_user"/> <button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" class="oe_highlight" groups="base.group_user"/> <button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" class="oe_highlight" groups="base.group_user"/>
<!-- <button name="action_assign" states="confirmed" string="Check Availability" type="object"/> --> <button name="action_assign" states="confirmed" string="Check Availability" type="object" class="oe_highlight"/>
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/> <button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="action_process" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/> <button name="action_process" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="%(action_stock_invoice_onshipping)d" string="Create Invoice/Refund" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" context="{'group_field_invisible': True}" type="action" class="oe_highlight" groups="base.group_user"/> <button name="%(action_stock_invoice_onshipping)d" string="Create Invoice/Refund" attrs="{'invisible': ['|','|',('state','&lt;&gt;','done'),('invoice_state','=','invoiced'),('invoice_state','=','none')]}" context="{'group_field_invisible': True}" type="action" class="oe_highlight" groups="base.group_user"/>
@ -909,7 +909,6 @@
</xpath> </xpath>
<xpath expr="/form/header//button[@name='draft_validate']" position="replace"> <xpath expr="/form/header//button[@name='draft_validate']" position="replace">
<button name="draft_validate" states="draft" string="Confirm &amp; Deliver" type="object" class="oe_highlight"/> <button name="draft_validate" states="draft" string="Confirm &amp; Deliver" type="object" class="oe_highlight"/>
<button name="action_assign" states="confirmed" string="Check Availability" type="object" class="oe_highlight"/>
</xpath> </xpath>
<xpath expr="/form/header//button[@name='action_process']" position="replace"> <xpath expr="/form/header//button[@name='action_process']" position="replace">
<button name="action_process" states="assigned" string="Deliver" type="object" class="oe_highlight"/> <button name="action_process" states="assigned" string="Deliver" type="object" class="oe_highlight"/>

View File

@ -27,7 +27,7 @@ class change_standard_price(osv.osv_memory):
_name = "stock.change.standard.price" _name = "stock.change.standard.price"
_description = "Change Standard Price" _description = "Change Standard Price"
_columns = { _columns = {
'new_price': fields.float('Price', required=True, digits_compute=dp.get_precision('Account'), 'new_price': fields.float('Price', required=True, digits_compute=dp.get_precision('Product Price'),
help="If cost price is increased, stock variation account will be debited " help="If cost price is increased, stock variation account will be debited "
"and stock output account will be credited with the value = (difference of amount * quantity available).\n" "and stock output account will be credited with the value = (difference of amount * quantity available).\n"
"If cost price is decreased, stock variation account will be creadited and stock input account will be debited."), "If cost price is decreased, stock variation account will be creadited and stock input account will be debited."),

View File

@ -27,6 +27,7 @@ from openerp import tools
from openerp.report import report_sxw from openerp.report import report_sxw
from openerp.report.interface import report_rml from openerp.report.interface import report_rml
from openerp.tools import to_xml from openerp.tools import to_xml
from openerp.tools.translate import _
class survey_browse_response(report_rml): class survey_browse_response(report_rml):
def create(self, cr, uid, ids, datas, context): def create(self, cr, uid, ids, datas, context):
@ -69,7 +70,7 @@ class survey_browse_response(report_rml):
rml +=""" rml +="""
<fill color="gray"/> <fill color="gray"/>
<setFont name="Helvetica" size="10"/> <setFont name="Helvetica" size="10"/>
<drawRightString x='"""+tools.ustr(float(_pageSize[0].replace('cm','')) - float(1.00))+'cm'+"""' y="0.6cm">Page : <pageNumber/> </drawRightString>""" <drawRightString x='"""+tools.ustr(float(_pageSize[0].replace('cm','')) - float(1.00))+'cm'+"""' y="0.6cm">"""+_('Page : ')+"""<pageNumber/> </drawRightString>"""
rml +="""</pageGraphics> rml +="""</pageGraphics>
</pageTemplate> </pageTemplate>
</template> </template>
@ -209,29 +210,29 @@ class survey_browse_response(report_rml):
resp_create = tools.ustr(time.strftime('%d-%m-%Y %I:%M:%S %p', time.strptime(response.date_create.split('.')[0], '%Y-%m-%d %H:%M:%S'))) resp_create = tools.ustr(time.strftime('%d-%m-%Y %I:%M:%S %p', time.strptime(response.date_create.split('.')[0], '%Y-%m-%d %H:%M:%S')))
rml += """<blockTable colWidths='""" + colwidth + """' style="Table_heading"> rml += """<blockTable colWidths='""" + colwidth + """' style="Table_heading">
<tr> <tr>
<td><para style="terp_default_9_Bold">Print Date : </para></td> <td><para style="terp_default_9_Bold">""" + _('Print Date : ') + """</para></td>
<td><para style="terp_default_9">""" + to_xml(rml_obj.formatLang(time.strftime("%Y-%m-%d %H:%M:%S"),date_time=True)) + """</para></td> <td><para style="terp_default_9">""" + to_xml(rml_obj.formatLang(time.strftime("%Y-%m-%d %H:%M:%S"),date_time=True)) + """</para></td>
<td><para style="terp_default_9"></para></td> <td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9_Bold">Answered by : </para></td> <td><para style="terp_default_9_Bold">""" +_('Answered by : ') + """</para></td>
<td><para style="terp_default_9">""" + to_xml(response.user_id.login or '') + """</para></td> <td><para style="terp_default_9">""" + to_xml(response.user_id.login or '') + """</para></td>
</tr> </tr>
<tr> <tr>
<td><para style="terp_default_9"></para></td> <td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9"></para></td> <td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9"></para></td> <td><para style="terp_default_9"></para></td>
<td><para style="terp_default_9_Bold">Answer Date : </para></td> <td><para style="terp_default_9_Bold">""" +_('Answer Date : ') + """</para></td>
<td><para style="terp_default_9">""" + to_xml(resp_create) + """</para></td> <td><para style="terp_default_9">""" + to_xml(resp_create) + """</para></td>
</tr> </tr>
</blockTable><para style="P2"></para>""" </blockTable><para style="P2"></para>"""
status = "Not Finished" status = _("Not Finished")
if response.state == "done": status = "Finished" if response.state == "done": status = _("Finished")
colwidth = str(tbl_width - 7) + "cm," colwidth = str(tbl_width - 7) + "cm,"
colwidth += "7cm" colwidth += "7cm"
rml += """<blockTable colWidths='""" + str(colwidth) + """' style="title_tbl"> rml += """<blockTable colWidths='""" + str(colwidth) + """' style="title_tbl">
<tr> <tr>
<td><para style="title">""" + to_xml(tools.ustr(survey.title)) + """</para><para style="P2"><font></font></para></td> <td><para style="title">""" + to_xml(tools.ustr(survey.title)) + """</para><para style="P2"><font></font></para></td>
<td><para style="descriptive_text_heading">Status :- """ + to_xml(tools.ustr(status)) + """</para><para style="P2"><font></font></para></td> <td><para style="descriptive_text_heading">"""+_('Status :- ')+ to_xml(tools.ustr(status)) + """</para><para style="P2"><font></font></para></td>
</tr> </tr>
</blockTable>""" </blockTable>"""
@ -242,7 +243,7 @@ class survey_browse_response(report_rml):
for page in survey.page_ids: for page in survey.page_ids:
rml += """<blockTable colWidths='""" + str(_tbl_widths) + """' style="page_tbl"> rml += """<blockTable colWidths='""" + str(_tbl_widths) + """' style="page_tbl">
<tr><td><para style="page">Page :- """ + to_xml(tools.ustr(page.title or '')) + """</para></td></tr> <tr><td><para style="page">"""+_('Page :- ') + to_xml(tools.ustr(page.title or '')) + """</para></td></tr>
</blockTable>""" </blockTable>"""
if page.note: if page.note:
rml += """<para style="P2"></para> rml += """<para style="P2"></para>
@ -302,7 +303,7 @@ class survey_browse_response(report_rml):
else: else:
rml +="""<blockTable colWidths='""" + str(_tbl_widths) + """' style="simple_table"> rml +="""<blockTable colWidths='""" + str(_tbl_widths) + """' style="simple_table">
<tr><td> <para style="response">No Answer</para></td> </tr> <tr><td> <para style="response">"""+ _('No Answer') + """</para></td> </tr>
</blockTable>""" </blockTable>"""
elif que.type in ['multiple_choice_only_one_ans','multiple_choice_multiple_ans']: elif que.type in ['multiple_choice_only_one_ans','multiple_choice_multiple_ans']:

View File

@ -173,8 +173,8 @@ class survey_question_wiz(osv.osv_memory):
# TODO: l10n, cleanup this code to make it readable. Or template? # TODO: l10n, cleanup this code to make it readable. Or template?
xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'}) xml_group = etree.SubElement(xml_form, 'group', {'col': '40', 'colspan': '4'})
record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']]) record = sur_response_obj.browse(cr, uid, context['response_id'][context['response_no']])
etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr('Answer Of :- ' + record.user_id.name + ', Date :- ' + record.date_create.split('.')[0] )), 'align':"0.0"}) etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(_('Answer Of :- ') + record.user_id.name + _(', Date :- ') + record.date_create.split('.')[0] )), 'align':"0.0"})
etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(" Answer :- " + str(context.get('response_no',0) + 1) +"/" + str(len(context.get('response_id',0))) )), 'align':"0.0"}) etree.SubElement(xml_group, 'label', {'string': to_xml(tools.ustr(_(" Answer :- ") + str(context.get('response_no',0) + 1) +"/" + str(len(context.get('response_id',0))) )), 'align':"0.0"})
if context.get('response_no',0) > 0: if context.get('response_no',0) > 0:
etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"}) etree.SubElement(xml_group, 'button', {'colspan':"1",'icon':"gtk-go-back",'name':"action_forward_previous",'string': tools.ustr("Previous Answer"),'type':"object"})
if context.get('response_no',0) + 1 < len(context.get('response_id',0)): if context.get('response_no',0) + 1 < len(context.get('response_id',0)):
@ -221,7 +221,7 @@ class survey_question_wiz(osv.osv_memory):
selection.append((tools.ustr(ans.id), ans.answer)) selection.append((tools.ustr(ans.id), ans.answer))
xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'}) xml_group = etree.SubElement(xml_group, 'group', {'col': '2', 'colspan': '2'})
etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"}) etree.SubElement(xml_group, 'field', {'readonly':str(readonly), 'name': tools.ustr(que.id) + "_selection"})
fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':"Answer"} fields[tools.ustr(que.id) + "_selection"] = {'type':'selection', 'selection' :selection, 'string':_('Answer')}
elif que_rec.type == 'multiple_choice_multiple_ans': elif que_rec.type == 'multiple_choice_multiple_ans':
xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'}) xml_group = etree.SubElement(xml_group, 'group', {'col': '4', 'colspan': '4'})
@ -374,10 +374,10 @@ class survey_question_wiz(osv.osv_memory):
if pre_button: if pre_button:
etree.SubElement(xml_footer, 'label', {'string': ""}) etree.SubElement(xml_footer, 'label', {'string': ""})
etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':"Previous",'type':"object"}) etree.SubElement(xml_footer, 'button', {'name':"action_previous",'string':_('Previous'),'type':"object"})
but_string = "Next" but_string = _('Next')
if int(page_number) + 1 == total_pages: if int(page_number) + 1 == total_pages:
but_string = "Done" but_string = _('Done')
if context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context.get('response_no',0) + 1 == len(context.get('response_id',0)): if context.has_key('active') and context.get('active',False) and int(page_number) + 1 == total_pages and context.has_key('response_id') and context.has_key('response_no') and context.get('response_no',0) + 1 == len(context.get('response_id',0)):
etree.SubElement(xml_footer, 'label', {'string': ""}) etree.SubElement(xml_footer, 'label', {'string': ""})
etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"}) etree.SubElement(xml_footer, 'button', {'special' : 'cancel','string': tools.ustr("Done") ,'context' : tools.ustr(context), 'class':"oe_highlight"})
@ -390,8 +390,8 @@ class survey_question_wiz(osv.osv_memory):
else: else:
etree.SubElement(xml_footer, 'label', {'string': ""}) etree.SubElement(xml_footer, 'label', {'string': ""})
etree.SubElement(xml_footer, 'button', {'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"}) etree.SubElement(xml_footer, 'button', {'name':"action_next",'string': tools.ustr(but_string) ,'type':"object",'context' : tools.ustr(context), 'class':"oe_highlight"})
etree.SubElement(xml_footer, 'label', {'string': "or"}) etree.SubElement(xml_footer, 'label', {'string': _('or')})
etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':"Exit",'class':"oe_link"}) etree.SubElement(xml_footer, 'button', {'special': "cancel",'string':_('Exit'),'class':"oe_link"})
etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"}) etree.SubElement(xml_footer, 'label', {'string': tools.ustr(page_number+ 1) + "/" + tools.ustr(total_pages), 'class':"oe_survey_title_page oe_right"})
root = xml_form.getroottree() root = xml_form.getroottree()