Denis Ledoux 2013-09-18 18:13:05 +02:00
commit 546a191f0a
97 changed files with 981 additions and 229 deletions

View File

@ -137,16 +137,27 @@ class account_account_type(osv.osv):
_name = "account.account.type"
_description = "Account Type"
def _get_current_report_type(self, cr, uid, ids, name, arg, context=None):
def _get_financial_report_ref(self, cr, uid, context=None):
obj_data = self.pool.get('ir.model.data')
obj_financial_report = self.pool.get('account.financial.report')
financial_report_ref = {}
for key, financial_report in [
('asset','account_financial_report_assets0'),
('liability','account_financial_report_liability0'),
('income','account_financial_report_income0'),
('expense','account_financial_report_expense0'),
]:
try:
financial_report_ref[key] = obj_financial_report.browse(cr, uid,
obj_data.get_object_reference(cr, uid, 'account', financial_report)[1],
context=context)
except ValueError:
pass
return financial_report_ref
def _get_current_report_type(self, cr, uid, ids, name, arg, context=None):
res = {}
financial_report_ref = {
'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
}
financial_report_ref = self._get_financial_report_ref(cr, uid, context=context)
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = 'none'
for key, financial_report in financial_report_ref.items():
@ -157,15 +168,9 @@ class account_account_type(osv.osv):
def _save_report_type(self, cr, uid, account_type_id, field_name, field_value, arg, context=None):
field_value = field_value or 'none'
obj_data = self.pool.get('ir.model.data')
obj_financial_report = self.pool.get('account.financial.report')
#unlink if it exists somewhere in the financial reports related to BS or PL
financial_report_ref = {
'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
}
financial_report_ref = self._get_financial_report_ref(cr, uid, context=context)
for key, financial_report in financial_report_ref.items():
list_ids = [x.id for x in financial_report.account_type_ids]
if account_type_id in list_ids:
@ -1258,6 +1263,10 @@ class account_move(osv.osv):
return [('id', 'in', tuple(ids))]
return [('id', '=', '0')]
def _get_move_from_lines(self, cr, uid, ids, context=None):
line_obj = self.pool.get('account.move.line')
return [line.move_id.id for line in line_obj.browse(cr, uid, ids, context=context)]
_columns = {
'name': fields.char('Number', size=64, required=True),
'ref': fields.char('Reference', size=64),
@ -1267,7 +1276,10 @@ class account_move(osv.osv):
help='All manually created new journal entries are usually in the status \'Unposted\', but you can set the option to skip that status on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' status.'),
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store={
_name: (lambda self, cr,uid,ids,c: ids, ['line_id'], 10),
'account.move.line': (_get_move_from_lines, ['partner_id'],10)
}),
'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True),
'narration':fields.text('Internal Note'),
@ -1404,14 +1416,17 @@ class account_move(osv.osv):
l[2]['period_id'] = default_period
context['period_id'] = default_period
if 'line_id' in vals:
if vals.get('line_id', False):
c = context.copy()
c['novalidate'] = True
c['period_id'] = vals['period_id'] if 'period_id' in vals else self._get_period(cr, uid, context)
c['journal_id'] = vals['journal_id']
if 'date' in vals: c['date'] = vals['date']
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:
result = super(account_move, self).create(cr, uid, vals, context)
return result
@ -1633,9 +1648,11 @@ class account_move(osv.osv):
else:
# We can't validate it (it's unbalanced)
# Setting the lines as draft
obj_move_line.write(cr, uid, line_ids, {
'state': 'draft'
}, context, check=False)
not_draft_line_ids = list(set(line_ids) - set(line_draft_ids))
if not_draft_line_ids:
obj_move_line.write(cr, uid, not_draft_line_ids, {
'state': 'draft'
}, context, check=False)
# Create analytic lines for the valid moves
for record in valid_moves:
obj_move_line.create_analytic_lines(cr, uid, [line.id for line in record.line_id], context)
@ -3029,22 +3046,23 @@ class wizard_multi_charts_accounts(osv.osv_memory):
'complete_tax_set': fields.boolean('Complete Set of Taxes', help='This boolean helps you to choose if you want to propose to the user to encode the sales and purchase rates or use the usual m2o fields. This last choice assumes that the set of tax defined for the chosen template is complete'),
}
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
currency_id = False
if company_id:
currency_id = self.pool.get('res.company').browse(cr, uid, company_id, context=context).currency_id.id
return {'value': {'currency_id': currency_id}}
def onchange_tax_rate(self, cr, uid, ids, rate=False, context=None):
return {'value': {'purchase_tax_rate': rate or False}}
def onchange_chart_template_id(self, cr, uid, ids, chart_template_id=False, context=None):
res = {}
tax_templ_obj = self.pool.get('account.tax.template')
ir_values = self.pool.get('ir.values')
res['value'] = {'complete_tax_set': False, 'sale_tax': False, 'purchase_tax': False}
if chart_template_id:
data = self.pool.get('account.chart.template').browse(cr, uid, chart_template_id, context=context)
res['value'].update({'complete_tax_set': data.complete_tax_set})
#set currecy_id based on selected COA template using ir.vaalues else current users company's currency
value_id = ir_values.search(cr, uid, [('model', '=', 'account.chart.template'), ('res_id', '=', chart_template_id)], limit=1, context=context)
if value_id:
currency_id = int(ir_values.browse(cr, uid, value_id[0], context=context).value)
else:
currency_id = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
res['value'].update({'complete_tax_set': data.complete_tax_set, 'currency_id': currency_id})
if data.complete_tax_set:
# default tax is given by the lowest sequence. For same sequence we will take the latest created as it will be the case for tax created while isntalling the generic chart of account
sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
@ -3060,6 +3078,7 @@ class wizard_multi_charts_accounts(osv.osv_memory):
def default_get(self, cr, uid, fields, context=None):
res = super(wizard_multi_charts_accounts, self).default_get(cr, uid, fields, context=context)
tax_templ_obj = self.pool.get('account.tax.template')
data_obj = self.pool.get('ir.model.data')
if 'bank_accounts_id' in fields:
res.update({'bank_accounts_id': [{'acc_name': _('Cash'), 'account_type': 'cash'},{'acc_name': _('Bank'), 'account_type': 'bank'}]})
@ -3076,7 +3095,13 @@ class wizard_multi_charts_accounts(osv.osv_memory):
ids = self.pool.get('account.chart.template').search(cr, uid, [('visible', '=', True)], context=context)
if ids:
if 'chart_template_id' in fields:
res.update({'only_one_chart_template': len(ids) == 1, 'chart_template_id': ids[0]})
#in order to set default chart which was last created set max of ids.
chart_id = max(ids)
if context.get("default_charts"):
data_ids = data_obj.search(cr, uid, [('model', '=', 'account.chart.template'), ('module', '=', context.get("default_charts"))], limit=1, context=context)
if data_ids:
chart_id = data_obj.browse(cr, uid, data_ids[0], context=context).res_id
res.update({'only_one_chart_template': len(ids) == 1, 'chart_template_id': chart_id})
if 'sale_tax' in fields:
sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id"
, "=", ids[0]), ('type_tax_use', 'in', ('sale','all'))], order="sequence")

View File

@ -10,7 +10,7 @@
</form>
<footer position="replace">
<footer>
<button name="action_next" type="object" string="Continue" class="oe_highlight"/>
<button name="action_next" context="{'default_charts':charts}" type="object" string="Continue" class="oe_highlight"/>
</footer>
</footer>
<separator string="title" position="replace">

View File

@ -1411,6 +1411,7 @@ class account_invoice_line(osv.osv):
_name = "account.invoice.line"
_description = "Invoice Line"
_order = "invoice_id,sequence,id"
_columns = {
'name': fields.text('Description', required=True),
'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."),
@ -1447,6 +1448,7 @@ class account_invoice_line(osv.osv):
'discount': 0.0,
'price_unit': _price_unit_default,
'account_id': _default_account_id,
'sequence': 10,
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):

View File

@ -192,6 +192,7 @@
<page string="Invoice">
<field context="{'partner_id': partner_id, 'price_type': context.get('price_type') or False, 'type': type}" name="invoice_line">
<tree string="Invoice lines" editable="bottom">
<field name="sequence" widget="handle" />
<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)"/>
<field name="name"/>

View File

@ -1283,7 +1283,7 @@ class account_move_line(osv.osv):
self.create(cr, uid, data, context)
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)
if journal.entry_posted and tmp:
move_obj.button_validate(cr,uid, [vals['move_id']], context)

View File

@ -2113,7 +2113,7 @@
<field name="chart_template_id" widget="selection" on_change="onchange_chart_template_id(chart_template_id)" domain="[('visible','=', True)]"/>
</group>
<group>
<field name="company_id" widget="selection" on_change="onchange_company_id(company_id)"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
<field name="company_id" widget="selection"/> <!-- we assume that this wizard will be run only by administrators and as this field may cause problem if hidden (because of the default company of the user removed from the selection because already configured), we simply choosed to remove the group "multi company" of it -->
<field name="currency_id" class="oe_inline"/>
<field name="sale_tax" attrs="{'invisible': [('complete_tax_set', '!=', True)]}" domain="[('chart_template_id', '=', chart_template_id),('parent_id','=',False),('type_tax_use','in',('sale','all'))]"/>
<label for="sale_tax_rate" string="Sale Tax" attrs="{'invisible': [('complete_tax_set', '=', True)]}"/>

View File

@ -7,16 +7,16 @@
<field name="model">account.analytic.chart</field>
<field name="arch" type="xml">
<form string="Analytic Account Charts" version="7.0">
<header>
<button name="analytic_account_chart_open_window" string="Open Charts" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</header>
<group string="Select the Period for Analysis" col="4">
<field name="from_date"/>
<field name="to_date"/>
<label string="(Keep empty to open the current situation)" colspan="4"/>
</group>
<footer>
<button name="analytic_account_chart_open_window" string="Open Charts" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>

View File

@ -38,6 +38,7 @@ class report_account_common(report_sxw.rml_parse, common_report_header):
'get_filter': self._get_filter,
'get_start_date':self._get_start_date,
'get_end_date':self._get_end_date,
'get_target_move': self._get_target_move,
})
self.context = context

View File

@ -166,11 +166,12 @@
<para style="Standard">
<font color="white"> </font>
</para>
<blockTable colWidths="163.0,163.0,163.0" style="Table2_header">
<blockTable colWidths="122.0,122.0,122.0,122.0" style="Table2_header">
<tr>
<td><para style="terp_tblheader_General_Centre">Chart of Accounts</para></td>
<td><para style="terp_tblheader_General_Centre">Fiscal Year</para></td>
<td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!='No Filters' and get_filter(data) ]]</para></td>
<td><para style="terp_tblheader_General_Centre">Target Moves</para></td>
</tr>
<tr>
<td><para style="terp_default_Centre_8">[[ get_account(data) or removeParentNode('para') ]]</para></td>
@ -197,6 +198,10 @@
</tr>
</blockTable>
</td>
<td>
<para style="terp_default_Centre_8">[[ get_target_move(data) ]]</para>
</td>
</tr>
</blockTable>
<para style="Standard">

View File

@ -54,7 +54,7 @@ class accounting_report(osv.osv_memory):
'target_move': 'posted',
'account_report_id': _get_account_report,
}
def _build_comparison_context(self, cr, uid, ids, data, context=None):
if context is None:
context = {}
@ -62,6 +62,7 @@ class accounting_report(osv.osv_memory):
result['fiscalyear'] = 'fiscalyear_id_cmp' in data['form'] and data['form']['fiscalyear_id_cmp'] or False
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['chart_account_id'] = 'chart_account_id' in data['form'] and data['form']['chart_account_id'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
if data['form']['filter_cmp'] == 'filter_date':
result['date_from'] = data['form']['date_from_cmp']
result['date_to'] = data['form']['date_to_cmp']
@ -86,7 +87,7 @@ class accounting_report(osv.osv_memory):
return res
def _print_report(self, cr, uid, ids, data, context=None):
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter'], context=context)[0])
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter','target_move'], context=context)[0])
return {
'type': 'ir.actions.report.xml',
'report_name': 'account.financial.report',

View File

@ -157,8 +157,8 @@ class account_invoice_refund(osv.osv_memory):
for line in movelines:
if line.account_id.id == inv.account_id.id:
to_reconcile_ids[line.account_id.id] = [line.id]
if type(line.reconcile_id) != osv.orm.browse_null:
reconcile_obj.unlink(cr, uid, line.reconcile_id.id)
if line.reconcile_id:
line.reconcile_id.unlink()
inv_obj.signal_invoice_open(cr, uid, [refund.id])
refund = inv_obj.browse(cr, uid, refund_id[0], context=context)
for tmpline in refund.move_id.line_id:

View File

@ -154,6 +154,7 @@ class account_common_report(osv.osv_memory):
result['fiscalyear'] = 'fiscalyear_id' in data['form'] and data['form']['fiscalyear_id'] or False
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['chart_account_id'] = 'chart_account_id' in data['form'] and data['form']['chart_account_id'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
if data['form']['filter'] == 'filter_date':
result['date_from'] = data['form']['date_from']
result['date_to'] = data['form']['date_to']

View File

@ -295,10 +295,6 @@ class account_analytic_account(osv.osv):
args=[]
if context is None:
context={}
if context.get('current_model') == 'project.project':
project_obj = self.pool.get("account.analytic.account")
project_ids = project_obj.search(cr, uid, args)
return self.name_get(cr, uid, project_ids, context=context)
if name:
account_ids = self.search(cr, uid, [('code', '=', name)] + args, limit=limit, context=context)
if not account_ids:

View File

@ -578,8 +578,7 @@ property or property parameter."),
def do_accept(self, cr, uid, ids, context=None, *args):
"""
Update state of invitation as Accepted and if the invited user is other
then event user it will make a copy of this event for invited user.
Marks event invitation as Accepted.
@param cr: the current row, from the database cursor
@param uid: the current user's ID for security checks
@param ids: list of calendar attendee's IDs
@ -589,15 +588,7 @@ property or property parameter."),
if context is None:
context = {}
for vals in self.browse(cr, uid, ids, context=context):
if vals.ref and vals.ref.user_id:
mod_obj = self.pool[vals.ref._name]
res=mod_obj.read(cr,uid,[vals.ref.id],['duration','class'],context)
defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id,'duration':res[0]['duration'],'class':res[0]['class']}
mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
return True
return self.write(cr, uid, ids, {'state': 'accepted'}, context)
def do_decline(self, cr, uid, ids, context=None, *args):
"""
@ -1126,12 +1117,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
for partner in event.partner_ids:
if partner.id in attendees:
continue
local_context = context.copy()
local_context.pop('default_state', None)
att_id = self.pool.get('calendar.attendee').create(cr, uid, {
'partner_id': partner.id,
'user_id': partner.user_ids and partner.user_ids[0].id or False,
'ref': self._name+','+str(event.id),
'email': partner.email
}, context=context)
}, context=local_context)
if partner.email:
mail_to = mail_to + " " + partner.email
self.write(cr, uid, [event.id], {
@ -1215,20 +1208,44 @@ rule or repeating pattern of time to exclude from the recurring rule."),
new_rrule_str = ';'.join(new_rrule_str)
rdates = get_recurrent_dates(str(new_rrule_str), exdate, event_date, data['exrule'])
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:
if arg[0] in ('date', 'date_deadline'):
if (arg[1]=='='):
ok = ok and r_date.strftime('%Y-%m-%d')==arg[2]
if (arg[1]=='>'):
ok = ok and r_date.strftime('%Y-%m-%d')>arg[2]
if (arg[1]=='<'):
ok = ok and r_date.strftime('%Y-%m-%d')<arg[2]
if (arg[1]=='>='):
ok = ok and r_date.strftime('%Y-%m-%d')>=arg[2]
if (arg[1]=='<='):
ok = ok and r_date.strftime('%Y-%m-%d')<=arg[2]
if not ok:
if str(arg[0]) in (str('date'), str('date_deadline')):
if (arg[1] == '='):
ok = r_date.strftime('%Y-%m-%d')==arg[2]
if (arg[1] == '>'):
ok = r_date.strftime('%Y-%m-%d')>arg[2]
if (arg[1] == '<'):
ok = r_date.strftime('%Y-%m-%d')<arg[2]
if (arg[1] == '>='):
ok = r_date.strftime('%Y-%m-%d')>=arg[2]
if (arg[1] == '<='):
ok = r_date.strftime('%Y-%m-%d')<=arg[2]
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
idval = real_id2base_calendar_id(data['id'], r_date.strftime("%Y-%m-%d %H:%M:%S"))
result.append(idval)
@ -1353,18 +1370,17 @@ rule or repeating pattern of time to exclude from the recurring rule."),
for arg in args:
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):
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":
new_id = get_real_ids(arg[2])
new_arg = (arg[0], arg[1], new_id)
new_args.append(new_arg)
#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)
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:
return len(res)
elif limit:
@ -1443,6 +1459,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
vals['vtimezone'] = vals['vtimezone'][40:]
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):
self.create_attendees(cr, uid, ids, context)
@ -1561,6 +1585,21 @@ rule or repeating pattern of time to exclude from the recurring rule."),
self.unlink_events(cr, uid, ids, context=context)
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):
if context is None:
context = {}
@ -1568,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/'):
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)
alarm_obj = self.pool.get('res.alarm')
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
self.create_attendees(cr, uid, [res], context)

View File

@ -126,7 +126,7 @@ class crm_case_section(osv.osv):
'note': fields.text('Description'),
'working_hours': fields.float('Working Hours', digits=(16, 2)),
'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="The email address associated with this team. New emails received will automatically "
"create new leads assigned to the team."),
'open_lead_ids': fields.one2many('crm.lead', 'section_id',

View File

@ -669,7 +669,7 @@ class crm_lead(base_stage, format_address, osv.osv):
# Merge notifications about loss of information
opportunities = [highest]
opportunities.extend(opportunities_rest)
self._merge_notify(cr, uid, highest, opportunities, context=context)
self._merge_notify(cr, uid, highest.id, opportunities, context=context)
# Check if the stage is in the stages of the sales team. If not, assign the stage with the lowest sequence
if merged_data.get('section_id'):
section_stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('section_ids', 'in', merged_data['section_id']), ('type', '=', merged_data.get('type'))], order='sequence', context=context)

View File

@ -36,13 +36,6 @@ def _employee_get(obj, cr, uid, context=None):
class hr_expense_expense(osv.osv):
def copy(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if not default: default = {}
default.update({'date_confirm': False, 'date_valid': False, 'user_valid': False})
return super(hr_expense_expense, self).copy(cr, uid, id, default, context=context)
def _amount(self, cr, uid, ids, field_name, arg, context=None):
res= {}
for expense in self.browse(cr, uid, ids, context=context):
@ -116,7 +109,11 @@ class hr_expense_expense(osv.osv):
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default.update(account_move_id=False)
default.update(
account_move_id=False,
date_confirm=False,
date_valid=False,
user_valid=False)
return super(hr_expense_expense, self).copy(cr, uid, id, default=default, context=context)
def unlink(self, cr, uid, ids, context=None):

View File

@ -503,7 +503,7 @@ class hr_job(osv.osv):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'survey_id': fields.many2one('survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
}

View File

@ -458,7 +458,7 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
THEN (SUM(total_attendance) +
CASE WHEN current_date <> name
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
)
ELSE SUM(total_attendance)

View File

@ -254,6 +254,13 @@
<field name="property_account_income_categ" ref="411_01"/>
</record>
<record id="ar_chart_template_value" model="ir.values">
<field name="name">Argentina - Plan de Cuentas</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="ar_chart_template"/>
<field name="value" ref="base.ARS"/>
</record>
</data>

View File

@ -2519,6 +2519,13 @@
<field name="property_account_expense" ref="chart5000"/>
<field name="property_account_income" ref="chart4000"/>
</record>
<record id="austria_chart_template_value" model="ir.values">
<field name="name">Austria - Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="austria_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>

View File

@ -14,6 +14,13 @@
<field name="property_account_income_categ" ref="a_sale"/>
<field name="spoken_languages" eval="'nl_BE'"/>
</record>
<record id="l10nbe_chart_template_value" model="ir.values">
<field name="name">Belgian PCMN</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nbe_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>

View File

@ -247,9 +247,9 @@ class partner_vat_intra(osv.osv_memory):
for client in xml_data['clientlist']:
if not client['vatnum']:
raise osv.except_osv(_('Insufficient Data!'),_('No vat number defined for %s.') % client['partner_name'])
data_clientinfo +='\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount)s</ns2:Amount>\n\t\t</ns2:IntraClient>' % (client)
data_clientinfo +='\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount).2f</ns2:Amount>\n\t\t</ns2:IntraClient>' % (client)
data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum)s">' % (xml_data)
data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum).2f">' % (xml_data)
data_file += data_head + data_decl + data_comp_period + data_clientinfo + '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' % (xml_data)
context['file_save'] = data_file

View File

@ -241,11 +241,11 @@ class account_coda_import(osv.osv_memory):
if statement['debit'] == '1': # 1=Debit
statement['balance_end_real'] = - statement['balance_end_real']
if statement['balance_end_realDate']:
period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['balance_end_realDate']), ('date_stop', '>=', statement['balance_end_realDate'])])
period_id = self.pool.get('account.period').search(cr, uid, [('company_id', '=', statement['journal_id'].company_id.id), ('date_start', '<=', statement['balance_end_realDate']), ('date_stop', '>=', statement['balance_end_realDate'])])
else:
period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['date']), ('date_stop', '>=', statement['date'])])
period_id = self.pool.get('account.period').search(cr, uid, [('company_id', '=', statement['journal_id'].company_id.id), ('date_start', '<=', statement['date']), ('date_stop', '>=', statement['date'])])
if not period_id and len(period_id) == 0:
raise osv.except_osv(_('Error') + 'R0002', _("The CODA Statement New Balance date doesn't fall within a defined Accounting Period! Please create the Accounting Period for date %s.") % statement['balance_end_realDate'])
raise osv.except_osv(_('Error') + 'R0002', _("The CODA Statement New Balance date doesn't fall within a defined Accounting Period! Please create the Accounting Period for date %s for the company %s.") % (statement['balance_end_realDate'], statement['journal_id'].company_id.name))
statement['period_id'] = period_id[0]
elif line[0] == '9':
statement['balanceMin'] = float(rmspaces(line[22:37])) / 1000

View File

@ -251,6 +251,13 @@
<field name="property_account_income_categ" ref="411_01"/>
</record>
<record id="bo_chart_template_value" model="ir.values">
<field name="name">Bolivia - Plan de Cuentas</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="bo_chart_template"/>
<field name="value" ref="base.BOB"/>
</record>
</data>

View File

@ -12,6 +12,14 @@
<field name="property_account_expense_categ" ref="account_template_3010103010000" />
<field name="property_account_income_categ" ref="account_template_3010101010200" />
</record>
<record id="l10n_br_account_chart_template_value" model="ir.values">
<field name="name">Planilha de Contas Brasileira</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_br_account_chart_template"/>
<field name="value" ref="base.BRL"/>
</record>
</data>
</openerp>

View File

@ -14,6 +14,13 @@
<field name="property_account_income_categ" ref="chart411_en"/>
<field name="property_account_expense_categ" ref="chart5111_en"/>
</record>
<record id="ca_en_chart_template_en_value" model="ir.values">
<field name="name">Canada - Chart of Accounts for english-speaking provinces</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="ca_en_chart_template_en"/>
<field name="value" ref="base.CAD"/>
</record>
<record id="stock.property_stock_account_input_categ" model="ir.property">
<field eval="'account.account,'+str(ref('chart2141_en'))" model="account.account" name="value"/>

View File

@ -13,6 +13,14 @@
<field name="property_account_income_categ" ref="chart411_fr"/>
<field name="property_account_expense_categ" ref="chart5111_fr"/>
</record>
<record id="ca_fr_chart_template_fr_value" model="ir.values">
<field name="name">Canada - Plan comptable pour les provinces francophones</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="ca_fr_chart_template_fr"/>
<field name="value" ref="base.CAD"/>
</record>
<record id="stock.property_stock_account_input_categ" model="ir.property">
<field eval="'account.account,'+str(ref('chart2171_fr'))" model="account.account" name="value"/>

View File

@ -11813,5 +11813,12 @@
<field name="code_digits" eval="0"/>
<field name="spoken_languages" eval="'it_IT;de_DE'"/>
</record>
<record id="l10nch_chart_template_value" model="ir.values">
<field name="name">Plan comptable STERCHI</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nch_chart_template"/>
<field name="value" ref="base.CHF"/>
</record>
</data>
</openerp>

View File

@ -249,7 +249,13 @@
<field name="property_account_expense_categ" ref="61_01"/>
<field name="property_account_income_categ" ref="411_01"/>
</record>
<record id="cl_chart_template_value" model="ir.values">
<field name="name">Chile - Plan de Cuentas</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="cl_chart_template"/>
<field name="value" ref="base.AUD"/>
</record>
</data>

View File

@ -958,6 +958,13 @@
<field name="property_account_expense_categ" ref="chart1401"/>
<field name="property_account_income_categ" ref="chart6001"/>
</record>
<record id="l10n_chart_china_value" model="ir.values">
<field name="name">中国会计科目表</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_chart_china"/>
<field name="value" ref="base.CNY"/>
</record>
<!-- 增值税 -->
<record id="vats" model="account.tax.template">
<field name="chart_template_id" ref="l10n_chart_china"/>

View File

@ -103349,6 +103349,13 @@ participacion, de conformidad con las disposiciones legales vigentes.
<field name="property_account_expense_categ" ref="chart529595999"/>
<field name="property_account_income_categ" ref="chart413595999"/>
</record>
<record id="vauxoo_mx_chart_template_value" model="ir.values">
<field name="name">Unique Account Chart - PUC</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="vauxoo_mx_chart_template"/>
<field name="value" ref="base.COP"/>
</record>
</data>
</openerp>

View File

@ -17,6 +17,13 @@
<field name="property_account_income_categ" ref="account_account_template_0_410001"/>
<field name="property_account_expense_categ" ref="account_account_template_0_511301"/>
</record>
<record id="account_chart_template_0_value" model="ir.values">
<field name="name">Costa Rica - Company 0</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_0"/>
<field name="value" ref="base.CRC"/>
</record>
<record id="account_chart_template_x" model="account.chart.template">
<field name="name">Costa Rica - Company 1</field>
<field name="account_root_id" ref="account_account_template_x000000"/>
@ -29,5 +36,12 @@
<field name="property_account_income_categ" ref="account_account_template_x410001"/>
<field name="property_account_expense_categ" ref="account_account_template_x511301"/>
</record>
<record id="account_chart_template_x_value" model="ir.values">
<field name="name">Costa Rica - Company 1</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_x"/>
<field name="value" ref="base.CRC"/>
</record>
</data>
</openerp>

View File

@ -13,5 +13,12 @@
<field name="property_account_expense_categ" ref="account_3400"/>
<field name="property_account_income_categ" ref="account_8400"/>
</record>
<record id="l10n_de_chart_template_value" model="ir.values">
<field name="name">Deutscher Kontenplan SKR03</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_de_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -13,5 +13,12 @@
<field name="property_account_expense_categ" ref="chart_skr04_5400"/>
<field name="property_account_income_categ" ref="chart_skr04_4400"/>
</record>
<record id="l10n_chart_de_skr04_value" model="ir.values">
<field name="name">Deutscher Kontenplan SKR04</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_chart_de_skr04"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -4203,6 +4203,13 @@
<field name="property_account_payable" ref="5"/>
<field name="property_account_expense_categ" ref="60101"/>
<field name="property_account_income_categ" ref="710101"/>
</record>
<record id="ec_chart_template_value" model="ir.values">
<field name="name">Ecuador - Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="ec_chart_template"/>
<field name="value" ref="base.USD"/>
</record>
</data>

View File

@ -13334,5 +13334,12 @@
<field name="property_account_expense_categ" ref="pgc_600_child"/>
<field name="property_account_income_categ" ref="pgc_7000_child"/>
</record>
<record id="l10nES_chart_template_value" model="ir.values">
<field name="name">Plantilla PGCE completo 2008</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nES_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -12421,6 +12421,13 @@
<field name="property_account_expense_categ" ref="pgc_assoc_600_child"/>
<field name="property_account_income_categ" ref="pgc_assoc_7000_child"/>
</record>
<record id="l10nES_chart_template_assoc_value" model="ir.values">
<field name="name">Plantilla PGCE Asociaciones 2008</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nES_chart_template_assoc"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -11465,5 +11465,12 @@
<field name="property_account_expense_categ" ref="pgc_pymes_600_child"/>
<field name="property_account_income_categ" ref="pgc_pymes_7000_child"/>
</record>
<record id="l10nES_chart_template_pymes_value" model="ir.values">
<field name="name">Plantilla PGCE PYMES 2008</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nES_chart_template_pymes"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -442,6 +442,13 @@
<field name="property_account_expense_categ" ref="pcg_6071"/>
<field name="property_account_income_categ" ref="pcg_7071"/>
</record>
<record id="l10n_fr_pcg_chart_template_value" model="ir.values">
<field name="name">Plan Comptable Général (France)</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_fr_pcg_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -22,7 +22,13 @@
<field name="property_account_expense_categ" ref="chartgr_64_98"/>
<field name="property_account_income_categ" ref="chartgr_71_00"/>
</record>
<record id="l10n_gr_chart_template_value" model="ir.values">
<field name="name">Πρότυπο Ελληνικού Λογιστικού Σχεδίου</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_gr_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
<record id="vat_code_balance_net" model="account.tax.code.template">
<field name="name">Υπόλοιπο ΦΠΑ </field>

View File

@ -32,6 +32,13 @@
<field name="property_account_income_categ" ref="cta410101"/>
<field name="property_account_expense_categ" ref="cta510101"/>
</record>
<record id="cuentas_plantilla_value" model="ir.values">
<field name="name">Plantilla de cuentas de Guatemala (sencilla)</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="cuentas_plantilla"/>
<field name="value" ref="base.QTQ"/>
</record>
<!-- Compras e IVA por Cobrar -->

View File

@ -18,6 +18,13 @@
<field name="property_account_income_categ" ref="cta410101"/>
<field name="property_account_expense_categ" ref="cta510101"/>
</record>
<record id="cuentas_plantilla_value" model="ir.values">
<field name="name">Plantilla de cuentas de Honduras (sencilla)</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="cuentas_plantilla"/>
<field name="value" ref="base.HNL"/>
</record>
<!-- Compras e ISV por Cobrar -->

View File

@ -16,6 +16,14 @@
<field name="property_account_expense_categ" ref="kp_rrif4199"/>
<field name="property_account_income_categ" ref="kp_rrif7500"/>
</record>
<record id="l10n_hr_chart_template_rrif_value" model="ir.values">
<field name="name">RRIF-ov računski plan za poduzetnike</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_hr_chart_template_rrif"/>
<field name="value" ref="base.HRK"/>
</record>
</data>
</openerp>

View File

@ -515,7 +515,13 @@
<field name="property_account_expense_categ" ref="a540"/>
<field name="property_account_income_categ" ref="a311"/>
</record>
<record id="indian_chart_template_private_value" model="ir.values">
<field name="name">India - Chart of Accounts for Private Ltd/Partnership</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="indian_chart_template_private"/>
<field name="value" ref="base.INR"/>
</record>
</data>
</openerp>

View File

@ -669,6 +669,13 @@
<field name="property_account_expense_categ" ref="p41010"/>
<field name="property_account_income_categ" ref="p31010"/>
</record>
<record id="indian_chart_template_public_value" model="ir.values">
<field name="name">India - Chart of Accounts for Public Ltd</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="indian_chart_template_public"/>
<field name="value" ref="base.INR"/>
</record>
</data>
</openerp>

View File

@ -12,5 +12,12 @@
<field name="property_account_expense_categ" ref="4101"/>
<field name="property_account_income_categ" ref="3101"/>
</record>
<record id="l10n_it_chart_template_generic_value" model="ir.values">
<field name="name">Italy - Generic Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_it_chart_template_generic"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -14,6 +14,13 @@
<field name="property_account_income_opening" ref="lu_2011_account_141"/>
<field name="property_account_expense_opening" ref="lu_2011_account_141"/>
</record>
<record id="lu_2011_chart_1_value" model="ir.values">
<field name="name">PCMN Luxembourg</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="lu_2011_chart_1"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>

View File

@ -742,7 +742,15 @@
<field name="account_root_id" ref="pcg_0"/>
<field name="tax_code_root_id" ref="vat_ma_tax_root"/>
<field name="bank_account_view_id" ref="pcg_514"/>
<field name="property_account_receivable" ref="pcg_3488"/>
<field name="property_account_payable" ref="pcg_4488"/>
</record>
<record id="l10n_kzc_temp_chart_value" model="ir.values">
<field name="name">compta Kazacube</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10n_kzc_temp_chart"/>
<field name="value" ref="base.MAD"/>
</record>
<record model="account.tax.template" id="tva_exo">

View File

@ -3696,6 +3696,13 @@ Cuentas del plan
<field name="property_stock_account_input_categ" ref="cuenta4111003000"/>
<field name="property_stock_account_output_categ" ref="cuenta4511003000"/>
</record>
<record id="vauxoo_mx_chart_template_value" model="ir.values">
<field name="name">Plan de Cuentas para Mexico</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="vauxoo_mx_chart_template"/>
<field name="value" ref="base.MXN"/>
</record>
</data>

View File

@ -4103,6 +4103,13 @@
<field name="property_account_expense_categ" ref="a_expense"/><!-- aankoop grondstoffen -->
<field name="property_account_income_categ" ref="a_sale"/> <!-- verkoop rekening -->
</record>
<record id="l10nnl_chart_template_value" model="ir.values">
<field name="name">Nederlands Grootboekschema</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10nnl_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
<!-- BTW Template
De volgende 2 velden worden gebruikt om een koppeling met het grootboek te maken. In de code wordt berekend

View File

@ -242,6 +242,13 @@
<field name="property_account_payable" ref="211"/>
<field name="property_account_expense_categ" ref="62_01"/>
<field name="property_account_income_categ" ref="411_01"/>
</record>
<record id="l10npa_chart_template_value" model="ir.values">
<field name="name">Panamá - Plan de Cuentas</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10npa_chart_template"/>
<field name="value" ref="base.PAB"/>
</record>

View File

@ -2259,7 +2259,13 @@
<field name="property_account_expense_categ" ref="6011_01"/>
<field name="property_account_income_categ" ref="70111_01"/>
</record>
<record id="pe_chart_template_value" model="ir.values">
<field name="name">Peru - Plan de Cuentas 2011</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="pe_chart_template"/>
<field name="value" ref="base.PEN"/>
</record>
</data>

View File

@ -3203,6 +3203,13 @@
<field name="property_account_expense_categ" ref="chart330020000"/>
<field name="property_account_income_categ" ref="chart773010000"/>
</record>
<record id="pl_chart_template_value" model="ir.values">
<field name="name">Polska - Plan kont</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="pl_chart_template"/>
<field name="value" ref="base.PLZ"/>
</record>
</data>
</openerp>
</openerp>

View File

@ -17,6 +17,13 @@
<field name="property_account_expense_categ" ref="chart_311"/>
<field name="property_reserve_and_surplus_account" ref="chart_811"/>
</record>
<record id="pt_chart_template_value" model="ir.values">
<field name="name">Portugal - Template do Plano de Contas SNC</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="pt_chart_template"/>
<field name="value" ref="base.EUR"/>
</record>
</data>
</openerp>
</openerp>

View File

@ -4589,5 +4589,13 @@
<field name="property_account_income_categ" ref="ro_pcg_sale"/> <!-- 707 -->
</record>
<record id="romania_chart_template_value" model="ir.values">
<field name="name">Romania - Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="romania_chart_template"/>
<field name="value" ref="base.ROL"/>
</record>
</data>
</openerp>

View File

@ -1850,6 +1850,13 @@
<field name="property_account_payable" ref="pcg_4011"/>
<field name="property_account_expense_categ" ref="pcg_6011" />
<field name="property_account_income_categ" ref="pcg_7011" />
</record>
<record id="syscohada_chart_template_value" model="ir.values">
<field name="name">SYSCOHADA - Plan de compte</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="syscohada_chart_template"/>
<field name="value" ref="base.XOF"/>
</record>
<record model="account.tax.code.template" id="tax_col_ht">

View File

@ -478,6 +478,13 @@
<field name="property_account_expense" ref="a_exp_office"/>
<field name="property_account_income" ref="a_sales"/>
</record>
<record id="chart_value" model="ir.values">
<field name="name">Thailand - Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="chart"/>
<field name="value" ref="base.THB"/>
</record>
<!-- TAXES -->

View File

@ -13,6 +13,13 @@
<field name="property_account_expense_categ" ref="tr150"/>
<field name="property_account_income_categ" ref="tr600"/>
</record>
<record id="l10ntr_tek_duzen_hesap_value" model="ir.values">
<field name="name">Tek Düzen Hesap Planı</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="l10ntr_tek_duzen_hesap"/>
<field name="value" ref="base.TRL"/>
</record>
</data>

View File

@ -6,52 +6,127 @@
<field name="name">Basic Chart of Account</field>
<field name="visible" eval="False" />
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
</record>
<record id="account_chart_template_basic_value" model="ir.values">
<field name="name">Basic Chart of Account</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_basic"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_cogs" model="account.chart.template">
<field name="name">Cost of Goods sold</field>
<field name="visible" eval="False" />
<field name="parent_id" ref="account_chart_template_basic"/>
<field name="currency_id" ref="base.USD"/>
<field name="complete_tax_set" eval="False" />
</record>
<record id="account_chart_template_cogs_value" model="ir.values">
<field name="name">Cost of Goods sold</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_cogs"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_advertising" model="account.chart.template">
<field name="name">Advertising</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_cogs"/>
</record>
<record id="account_chart_template_advertising_value" model="ir.values">
<field name="name">Advertising</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_advertising"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_agriculture" model="account.chart.template">
<field name="name">Agriculture</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_basic"/>
</record>
<record id="account_chart_template_agriculture_value" model="ir.values">
<field name="name">Agriculture</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_agriculture"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_construction" model="account.chart.template">
<field name="name">Construction Trades (Plumber, Electrician, HVAC, etc.)</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_cogs"/>
</record>
<record id="account_chart_template_construction_value" model="ir.values">
<field name="name">Construction Trades (Plumber, Electrician, HVAC, etc.)</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_construction"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_financial_service" model="account.chart.template">
<field name="name">Financial Services other than Accounting or Bookkeeping</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_cogs"/>
</record>
<record id="account_chart_template_financial_service_value" model="ir.values">
<field name="name">Financial Services other than Accounting or Bookkeeping</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_financial_service"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_general_service" model="account.chart.template">
<field name="name">General Service-Based Business</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_cogs"/>
</record>
<record id="account_chart_template_general_service_value" model="ir.values">
<field name="name">General Service-Based Business</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_general_service"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_legal_service" model="account.chart.template">
<field name="name">Legal Services</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_basic"/>
</record>
<record id="account_chart_template_legal_service_value" model="ir.values">
<field name="name">Legal Services</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_legal_service"/>
<field name="value" ref="base.USD"/>
</record>
<record id="account_chart_template_general_product" model="account.chart.template">
<field name="name">General Product-Based Business</field>
<field name="complete_tax_set" eval="False" />
<field name="currency_id" ref="base.USD"/>
<field name="parent_id" ref="account_chart_template_basic"/>
</record>
<record id="account_chart_template_general_product_value" model="ir.values">
<field name="name">General Product-Based Business</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="account_chart_template_general_product"/>
<field name="value" ref="base.USD"/>
</record>
</data>
</openerp>

View File

@ -6,6 +6,8 @@
<field name="account_root_id" ref="coa_basic"/>
<field name="bank_account_view_id" ref="cash_expenditure"/>
<field name="tax_code_root_id" ref="tax_code_chart_root"/>
<field name="property_account_receivable" ref="account_receivable"/>
<field name="property_account_payable" ref="account_payable"/>
</record>
<record id="account_chart_template_advertising" model="account.chart.template">
<field name="bank_account_view_id" ref="cash_expenditure"/>

View File

@ -1896,7 +1896,13 @@
<field name="property_account_income_categ" ref="uy_code_4100"/>
<field name="property_account_expense_categ" ref="uy_code_5100"/>
</record>
<record id="uy_chart_template_value" model="ir.values">
<field name="name">Plan de Cuentas Uruguay - Template</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="uy_chart_template"/>
<field name="value" ref="base.UYP"/>
</record>
</data>
</openerp>

View File

@ -3316,5 +3316,12 @@
<field name="property_account_expense_categ" ref="account_activa_account_7151001"/>
<field name="property_account_income_categ" ref="account_activa_account_5111001"/>
</record>
<record id="ve_chart_template_amd_value" model="ir.values">
<field name="name">Venezuelan - Account</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="ve_chart_template_amd"/>
<field name="value" ref="base.VUB"/>
</record>
</data>
</openerp>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record id="tax0sale" model="account.tax.template">
<record id="tax0all" model="account.tax.template">
<field name="chart_template_id" ref="ve_chart_template_amd"/>
<field name="name">Exento</field>
<field name="amount">0.00000</field>
<field name="type">percent</field>
<field name="type_tax_use">sale</field>
<field name="type_tax_use">all</field>
<field name="collected_id" ref="account_activa_account_2172003"/>
<field name="paid_id" ref="account_activa_account_2172003"/>
<field name="base_code_id" ref="vat_code_base_due"/>
@ -54,19 +54,6 @@
<field name="ref_base_code_id" ref="vat_code_receivable_net"/>
<field name="ref_tax_code_id" ref="vat_code_payable"/>
</record>
<record id="tax0purchase" model="account.tax.template">
<field name="chart_template_id" ref="ve_chart_template_amd"/>
<field name="name">Exento</field>
<field name="amount">0.00000</field>
<field name="type">percent</field>
<field name="type_tax_use">purchase</field>
<field name="collected_id" ref="account_activa_account_2172003"/>
<field name="paid_id" ref="account_activa_account_2172003"/>
<field name="base_code_id" ref="vat_code_base_due"/>
<field name="tax_code_id" ref="vat_code_due_tva"/>
<field name="ref_base_code_id" ref="vat_code_receivable_net"/>
<field name="ref_tax_code_id" ref="vat_code_payable"/>
</record>
<record id="tax1purchase" model="account.tax.template">
<field name="chart_template_id" ref="ve_chart_template_amd"/>
<field name="name">IVA (12.0%) compras</field>

View File

@ -2017,6 +2017,13 @@
<field name="property_account_income_categ" ref="chart5111" />
</record>
<record id="vn_template_value" model="ir.values">
<field name="name">VN - Chart of Accounts</field>
<field name="model">account.chart.template</field>
<field name="key">default</field>
<field name="res_id" ref="vn_template"/>
<field name="value" ref="base.VND"/>
</record>
</data>
</openerp>

View File

@ -76,7 +76,7 @@ class mail_group(osv.Model):
help="Small-sized photo of the group. It is automatically "\
"resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="The email address associated with this group. New emails received will automatically "
"create new topics."),
}

View File

@ -34,7 +34,7 @@ class res_users(osv.Model):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email address internally associated with this user. Incoming "\
"emails will appear in the user's notifications."),
}

View File

@ -158,6 +158,7 @@
<record id="view_res_partner_member_filter" model="ir.ui.view">
<field name="name">res.partner.select</field>
<field name="model">res.partner</field>
<field name="priority">50</field>
<field name="arch" type="xml">
<search string="Membership Partners">
<field name="membership_start" invisible="1"/>

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
# so the ymls are too complex to change at this stage
'test': [
'test/bom_with_service_type_product.yml',
'test/order_demo.yml',
'test/order_process.yml',
'test/cancel_order.yml',

View File

@ -318,9 +318,10 @@ class mrp_bom(osv.osv):
"""
routing_obj = self.pool.get('mrp.routing')
factor = factor / (bom.product_efficiency or 1.0)
factor = rounding(factor, bom.product_rounding)
if factor < bom.product_rounding:
factor = bom.product_rounding
max_rounding = max(bom.product_rounding, bom.product_uom.rounding)
factor = rounding(factor, max_rounding)
if factor < max_rounding:
factor = max_rounding
result = []
result2 = []
phantom = False
@ -600,12 +601,12 @@ class mrp_production(osv.osv):
"""
self.write(cr, uid, ids, {'state': 'picking_except'})
return True
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.
def _action_compute_lines(self, cr, uid, ids, properties=None, context=None):
""" Compute product_lines and workcenter_lines from BoM structure
@return: product_lines
"""
if properties is None:
properties = []
results = []
@ -613,13 +614,15 @@ class mrp_production(osv.osv):
uom_obj = self.pool.get('product.uom')
prod_line_obj = self.pool.get('mrp.production.product.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)
prod_line_obj.unlink(cr, SUPERUSER_ID, p_ids, context=context)
w_ids = workcenter_line_obj.search(cr, SUPERUSER_ID, [('production_id', '=', production.id)], context=context)
workcenter_line_obj.unlink(cr, SUPERUSER_ID, w_ids, context=context)
for production in self.browse(cr, uid, ids, context=context):
#unlink product_lines
prod_line_obj.unlink(cr, SUPERUSER_ID, [line.id for line in production.product_lines], 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_id = production.bom_id.id
if not bom_point:
@ -628,20 +631,33 @@ class mrp_production(osv.osv):
bom_point = bom_obj.browse(cr, uid, bom_id)
routing_id = bom_point.routing_id.id or False
self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})
if not bom_id:
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)
res = bom_obj._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties, routing_id=production.routing_id.id)
results = res[0]
results2 = res[1]
results = res[0] # product_lines
results2 = res[1] # workcenter_lines
# reset product_lines in production order
for line in results:
line['production_id'] = production.id
prod_line_obj.create(cr, uid, line)
#reset workcenter_lines in production order
for line in results2:
line['production_id'] = production.id
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):
""" Cancels the production order and related stock moves.
@ -668,8 +684,12 @@ class mrp_production(osv.osv):
move_obj = self.pool.get('stock.move')
self.write(cr, uid, ids, {'state': 'ready'})
for (production_id,name) in self.name_get(cr, uid, ids):
production = self.browse(cr, uid, production_id)
for production in self.browse(cr, uid, ids, context=context):
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:
move_obj.write(cr, uid, [production.move_prod_id.id],
{'location_id': production.location_dest_id.id})
@ -721,6 +741,10 @@ class mrp_production(osv.osv):
stock_mov_obj = self.pool.get('stock.move')
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
for produced_product in production.move_created_ids2:
if (produced_product.scrapped) or (produced_product.product_id.id != production.product_id.id):
@ -783,9 +807,9 @@ class mrp_production(osv.osv):
subproduct_factor = self._get_subproduct_factor(cr, uid, production.id, produce_product.id, context=context)
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]
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 :
stock_mov_obj.action_consume(cr, uid, [produce_product.id], (subproduct_factor * production_qty), context=context)
@ -857,13 +881,19 @@ class mrp_production(osv.osv):
"""
res = True
for production in self.browse(cr, uid, ids):
if not production.product_lines:
if not self.action_compute(cr, uid, [production.id]):
res = False
boms = self._action_compute_lines(cr, uid, [production.id])
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
def _get_auto_picking(self, cr, uid, production):
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):
procurement_order = self.pool.get('procurement.order')
@ -1011,11 +1041,13 @@ class mrp_production(osv.osv):
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)
shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,\
if shipment_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)
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)
self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id])
if shipment_id:
self.pool.get('stock.picking').signal_button_confirm(cr, uid, [shipment_id])
production.write({'state':'confirmed'}, context=context)
return shipment_id

View File

@ -1028,7 +1028,7 @@
<field name="name">Bill of Materials</field>
<field name="domain">[('bom_id','=',False)]</field>
<field name="res_model">mrp.bom</field>
<field name="view_type">tree</field>
<field name="view_type">form</field>
</record>
<record id="act_product_mrp_production" model="ir.actions.act_window">
<field name="context">{'search_default_product_id': [active_id]}</field>

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

@ -33,7 +33,13 @@ class TestMrpMulticompany(common.TransactionCase):
self.res_users = self.registry('res.users')
self.stock_location = self.registry('stock.location')
model, self.multicompany_user_id = self.ir_model_data.get_object_reference(cr, uid, 'stock', 'multicompany_user')
model, group_user_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
model, group_stock_manager_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'group_stock_manager')
model, company_2_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'res_company_2')
self.multicompany_user_id = self.res_users.create(cr, uid,
{'name': 'multicomp', 'login': 'multicomp',
'groups_id': [(6, 0, [group_user_id, group_stock_manager_id])],
'company_id': company_2_id, 'company_ids': [(6,0,[company_2_id])]})
def test_00_multicompany_user(self):

View File

@ -469,6 +469,11 @@ class pos_session(osv.osv):
context = {}
if not ids:
return {}
for session in self.browse(cr, uid, ids, context=context):
if session.user_id.id != uid:
raise osv.except_osv(
_('Error!'),
_("You cannot use the session of another users. This session is owned by %s. Please first close this one to use this point of sale." % session.user_id.name))
context.update({'active_id': ids[0]})
return {
'type' : 'ir.actions.client',
@ -492,9 +497,9 @@ class pos_order(osv.osv):
'user_id': order['user_id'] or False,
'session_id': order['pos_session_id'],
'lines': order['lines'],
'pos_reference':order['name']
'pos_reference':order['name'],
'partner_id': order.get('partner_id', False)
}, context)
for payments in order['statement_ids']:
payment = payments[2]
self.add_payment(cr, uid, order_id, {
@ -791,9 +796,18 @@ class pos_order(osv.osv):
"""Create a copy of order for refund order"""
clone_list = []
line_obj = self.pool.get('pos.order.line')
for order in self.browse(cr, uid, ids, context=context):
current_session_ids = self.pool.get('pos.session').search(cr, uid, [
('state', '!=', 'closed'),
('user_id', '=', uid)], context=context)
if not current_session_ids:
raise osv.except_osv(_('Error!'), _('To return product(s), you need to open a session that will be used to register the refund.'))
clone_id = self.copy(cr, uid, order.id, {
'name': order.name + ' REFUND',
'name': order.name + ' REFUND', # not used, name forced by create
'session_id': current_session_ids[0],
'date_order': time.strftime('%Y-%m-%d %H:%M:%S'),
}, context=context)
clone_list.append(clone_id)

View File

@ -151,24 +151,18 @@ class pos_details(report_sxw.rml_parse):
return self._ellipsis(name, maxlen, ' ...')
def _get_tax_amount(self, form):
res = {}
temp = {}
list_ids = []
temp2 = 0.0
taxes = {}
account_tax_obj = self.pool.get('account.tax')
user_ids = form['user_ids'] or self._get_all_users()
pos_order_obj = self.pool.get('pos.order')
pos_ids = pos_order_obj.search(self.cr, self.uid, [('date_order','>=',form['date_start'] + ' 00:00:00'),('date_order','<=',form['date_end'] + ' 23:59:59'),('state','in',['paid','invoiced','done']),('user_id','in',user_ids)])
temp.update({'name': ''})
for order in pos_order_obj.browse(self.cr, self.uid, pos_ids):
temp2 += order.amount_tax
for line in order.lines:
if len(line.product_id.taxes_id):
tax = line.product_id.taxes_id[0]
res[tax.name] = (line.price_unit * line.qty * (1-(line.discount or 0.0) / 100.0)) + (tax.id in list_ids and res[tax.name] or 0)
list_ids.append(tax.id)
temp.update({'name': tax.name})
temp.update({'amount': temp2})
return [temp] or False
line_taxes = account_tax_obj.compute_all(self.cr, self.uid, line.product_id.taxes_id, line.price_unit, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
for tax in line_taxes['taxes']:
taxes.setdefault(tax['id'], {'name': tax['name'], 'amount':0.0})
taxes[tax['id']]['amount'] += tax['amount']
return [value for value in taxes.values()] or False
def _get_user_names(self, user_ids):
user_obj = self.pool.get('res.users')

View File

@ -567,6 +567,7 @@
background:#fff;
border: 1px solid #fff;
border-radius: 3px;
overflow: hidden;
-webkit-box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
-moz-box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
box-shadow: 0px 2px 0px #dad8e4, 0px 1px 8px #636480;
@ -608,6 +609,8 @@
top:auto;
line-height: 14px;
width:100%;
overflow: hidden;
text-overflow: ellipsis;
background: -webkit-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
background: -moz-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
background: -ms-linear-gradient(-90deg,rgba(255,255,255,0),rgba(255,255,255,1), rgba(255,255,255,1));
@ -785,9 +788,11 @@
.point-of-sale .pos-sale-ticket table {
width: 100%;
border: 0;
table-layout: fixed;
}
.point-of-sale .pos-sale-ticket table td {
border: 0;
word-wrap: break-word;
}
@media print {
@ -886,14 +891,16 @@
.point-of-sale .scale-screen .product-name {
position: absolute;
left:0;
left:40px;
top:50px;
height:50px;
font-size:40px;
font-size:36px;
line-height:50px;
text-align:right;
right:275px;
color: #8d8d8d;
overflow: hidden;
text-overflow: ellipsis;
}
.point-of-sale .scale-screen .weight{
position: absolute;
@ -1057,6 +1064,7 @@
font-weight: bold;
width:80%;
overflow:hidden;
text-overflow: ellipsis;
}
.point-of-sale .order .orderline .price{
padding:0;

View File

@ -150,6 +150,9 @@ function openerp_pos_db(instance, module){
if(product.ean13){
str += '|' + product.ean13;
}
if(product.default_code){
str += '|' + product.default_code;
}
var packagings = this.packagings_by_product_id[product.id] || [];
for(var i = 0; i < packagings.length; i++){
str += '|' + packagings[i].ean;

View File

@ -27,7 +27,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
this.connection = new instance.web.JsonRPC();
this.connection.setup(url);
this.connection.session_id = _.uniqueId('posproxy');
this.bypass_proxy = false;
this.notifications = {};
@ -437,10 +437,9 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// The barcode readers acts as a keyboard, we catch all keyup events and try to find a
// barcode sequence in the typed keys, then act accordingly.
$('body').delegate('','keyup', function (e){
//console.log('keyup:'+String.fromCharCode(e.keyCode)+' '+e.keyCode,e);
this.handler = function(e){
//We only care about numbers
if (e.keyCode >= 48 && e.keyCode < 58){
if (e.which >= 48 && e.which < 58){
// The barcode reader sends keystrokes with a specific interval.
// We look if the typed keys fit in the interval.
@ -453,7 +452,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
timeStamp = new Date().getTime();
}
}
codeNumbers.push(e.keyCode - 48);
codeNumbers.push(e.which - 48);
lastTimeStamp = new Date().getTime();
if (codeNumbers.length === 13) {
//We have found what seems to be a valid codebar
@ -464,12 +463,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// NaN
codeNumbers = [];
}
});
};
$('body').on('keypress', this.handler);
},
// stops catching keyboard events
disconnect: function(){
$('body').undelegate('', 'keyup')
$('body').off('keypress', this.handler)
},
});

View File

@ -51,6 +51,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
'pos_config': null,
'units': null,
'units_by_id': null,
'pricelist': null,
'selectedOrder': null,
});
@ -102,10 +103,6 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
}).then(function(company_partners){
self.get('company').contact_address = company_partners[0].contact_address;
return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('company').currency_id[0]]]);
}).then(function(currencies){
self.set('currency',currencies[0]);
return self.fetch('product.uom', null, null);
}).then(function(units){
self.set('units',units);
@ -160,6 +157,14 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
}).then(function(shops){
self.set('shop',shops[0]);
return self.fetch('product.pricelist',['currency_id'],[['id','=',self.get('shop').pricelist_id[0]]]);
}).then(function(pricelists){
self.set('pricelist',pricelists[0]);
return self.fetch('res.currency',['symbol','position','rounding','accuracy'],[['id','=',self.get('pricelist').currency_id[0]]]);
}).then(function(currencies){
self.set('currency',currencies[0]);
return self.fetch('product.packaging',['ean','product_id']);
}).then(function(packagings){
self.db.add_packagings(packagings);
@ -170,7 +175,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
return self.fetch(
'product.product',
['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13',
['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code',
'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'],
[['sale_ok','=',true],['available_in_pos','=',true]],
{pricelist: self.get('shop').pricelist_id[0]} // context for price
@ -787,7 +792,7 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal
lines: orderLines,
statement_ids: paymentLines,
pos_session_id: this.pos.get('pos_session').id,
partner_id: this.pos.get('client') ? this.pos.get('client').id : undefined,
partner_id: this.get('client') ? this.get('client').id : undefined,
user_id: this.pos.get('cashier') ? this.pos.get('cashier').id : this.pos.get('user').id,
};
},

View File

@ -762,9 +762,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
this.product_categories_widget.reset_category();
this.pos_widget.order_widget.set_numpad_state(this.pos_widget.numpad.state);
if(this.pos.iface_vkeyboard){
this.pos_widget.onscreen_keyboard.connect();
}
if(this.pos_widget.screen_selector.current_mode === 'client'){
this.add_action_button({
@ -781,6 +778,9 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
this._super();
this.pos_widget.order_widget.set_numpad_state(null);
this.pos_widget.payment_screen.set_numpad_state(null);
if(this.pos.iface_vkeyboard && this.pos_widget.onscreen_keyboard){
this.pos_widget.onscreen_keyboard.hide();
}
},
});

View File

@ -27,9 +27,7 @@ function openerp_pos_keyboard(instance, module){ //module is instance.point_of_s
}
this.input_selector = options.input_selector || '.searchbox input';
//show the keyboard when the input zone is clicked.
$(this.input_selector).focus(function(){self.show();});
this.$target = null;
//Keyboard state
this.capslock = false;
@ -37,17 +35,23 @@ function openerp_pos_keyboard(instance, module){ //module is instance.point_of_s
this.numlock = false;
},
connect : function(){
connect : function($target){
var self = this;
$(this.input_selector).focus(function(){self.show();});
this.$target = $target;
$target.focus(function(){self.show();});
},
// Write a character to the input zone
writeCharacter: function(character){
var $input = $(this.input_selector);
$input[0].value += character;
$input.keydown();
$input.keyup();
var $input = this.$target;
if(character === '\n'){
$input.trigger($.Event('keydown',{which:13}));
$input.trigger($.Event('keyup',{which:13}));
}else{
$input[0].value += character;
$input.keydown();
$input.keyup();
}
},
// Sends a 'return' character to the input zone. TODO
@ -56,7 +60,7 @@ function openerp_pos_keyboard(instance, module){ //module is instance.point_of_s
// Removes the last character from the input zone.
deleteCharacter: function(){
var $input = $(this.input_selector);
var $input = this.$target;
var input_value = $input[0].value;
$input[0].value = input_value.substr(0, input_value.length - 1);
$input.keydown();
@ -65,7 +69,7 @@ function openerp_pos_keyboard(instance, module){ //module is instance.point_of_s
// Clears the content of the input zone.
deleteAllCharacters: function(){
var $input = $(this.input_selector);
var $input = this.$target;
$input[0].value = "";
$input.keydown();
$input.keyup();

View File

@ -530,7 +530,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
var cat = self.pos.db.get_category_by_id(id);
self.set_category(cat);
self.renderElement();
self.search_and_categories(cat);
});
});
// breadcrumb click actions
@ -539,9 +538,13 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
var category = self.pos.db.get_category_by_id(id);
self.set_category(category);
self.renderElement();
self.search_and_categories(category);
});
this.search_and_categories();
if(this.pos.iface_vkeyboard && this.pos_widget.onscreen_keyboard){
this.pos_widget.onscreen_keyboard.connect(this.$('.searchbox input'));
}
},
set_product_type: function(type){ // 'all' | 'weightable'
@ -553,7 +556,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
reset_category: function(){
this.set_category();
this.renderElement();
this.search_and_categories();
},
// empties the content of the search box
clear_search: function(){
var products = this.pos.db.get_product_by_category(this.category.id);
this.pos.get('products').reset(products);
this.$('.searchbox input').val('').focus();
this.$('.search-clear').fadeOut();
},
// filters the products, and sets up the search callbacks
@ -565,12 +575,20 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
self.pos.get('products').reset(products);
// filter the products according to the search string
this.$('.searchbox input').keyup(function(){
this.$('.searchbox input').keyup(function(event){
console.log('event',event);
query = $(this).val().toLowerCase();
if(query){
var products = self.pos.db.search_product_in_category(self.category.id, query);
self.pos.get('products').reset(products);
self.$('.search-clear').fadeIn();
if(event.which === 13){
if( self.pos.get('products').size() === 1 ){
self.pos.get('selectedOrder').addProduct(self.pos.get('products').at(0));
self.clear_search();
}
}else{
var products = self.pos.db.search_product_in_category(self.category.id, query);
self.pos.get('products').reset(products);
self.$('.search-clear').fadeIn();
}
}else{
var products = self.pos.db.get_product_by_category(self.category.id);
self.pos.get('products').reset(products);
@ -578,14 +596,9 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
}
});
this.$('.searchbox input').click(function(){}); //Why ???
//reset the search when clicking on reset
this.$('.search-clear').click(function(){
var products = self.pos.db.get_product_by_category(self.category.id);
self.pos.get('products').reset(products);
self.$('.searchbox input').val('').focus();
self.$('.search-clear').fadeOut();
self.clear_search();
});
},
});

View File

@ -565,6 +565,11 @@
Shop: <t t-esc="widget.shop_obj.name"/><br />
<br />
<table>
<colgroup>
<col width='50%' />
<col width='25%' />
<col width='25%' />
</colgroup>
<tr t-foreach="widget.currentOrderLines.toArray()" t-as="orderline">
<td>
<t t-esc="orderline.get_product().get('name')"/>

View File

@ -93,6 +93,7 @@ class product_pricelist(osv.osv):
_name = "product.pricelist"
_description = "Pricelist"
_order = 'name'
_columns = {
'name': fields.char('Pricelist Name',size=64, required=True, translate=True),
'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the pricelist without removing it."),
@ -111,6 +112,27 @@ class product_pricelist(osv.osv):
result.append((pl.id,name))
return result
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if name and operator == '=' and not args:
# search on the name of the pricelist and its currency, opposite of name_get(),
# Used by the magic context filter in the product search view.
query_args = {'name': name, 'limit': limit}
query = """SELECT p.id
FROM product_pricelist p JOIN
res_currency c ON (p.currency_id = c.id)
WHERE p.name || ' (' || c.name || ')' = %(name)s
ORDER BY p.name"""
if limit:
query += " LIMIT %(limit)s"
cr.execute(query, query_args)
ids = [r[0] for r in cr.fetchall()]
# regular search() to apply ACLs - may limit results below limit in some cases
ids = self.search(cr, uid, [('id', 'in', ids)], limit=limit, context=context)
if ids:
return self.name_get(cr, uid, ids, context)
return super(product_pricelist, self).name_search(
cr, uid, name, args, operator=operator, context=context, limit=limit)
def _get_currency(self, cr, uid, ctx):
comp = self.pool.get('res.users').browse(cr, uid, uid).company_id

View File

@ -415,6 +415,11 @@ class product_product(osv.osv):
pricelist = context.get('pricelist', False)
partner = context.get('partner', False)
if pricelist:
# Support context pricelists specified as display_name or ID for compatibility
if isinstance(pricelist, basestring):
pricelist_ids = self.pool.get('product.pricelist').name_search(
cr, uid, pricelist, operator='=', context=context, limit=1)
pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
for id in ids:
try:
price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, partner=partner, context=context)[pricelist]
@ -757,7 +762,7 @@ class product_product(osv.osv):
context = {}
if context and context.get('search_default_categ_id', False):
args.append((('categ_id', 'child_of', context['search_default_categ_id'])))
return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False)
return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
class product_packaging(osv.osv):

View File

@ -15,7 +15,7 @@
<filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
<field name="categ_id"/>
<group expand="0" string="Context...">
<field name="pricelist_id" context="{'pricelist': self}" groups="product.group_sale_pricelist"/>
<field name="pricelist_id" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group expand='0' string='Group by...'>

View File

@ -281,7 +281,7 @@ class project(osv.osv):
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'task_count': fields.function(_task_count, type='integer', string="Open Tasks"),
'color': fields.integer('Color Index'),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Internal email associated with this project. Incoming emails are automatically synchronized"
"with Tasks (or optionally Issues if the Issue Tracker module is installed)."),
'alias_model': fields.selection(_alias_models, "Alias Model", select=True, required=True,
@ -745,6 +745,16 @@ class task(base_stage, osv.osv):
new_name = _("%s (copy)") % (default.get('name', ''))
default.update({'name':new_name})
return super(task, self).copy_data(cr, uid, id, default, context)
def copy(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if default is None:
default = {}
stage = self._get_default_stage_id(cr, uid, context=context)
if stage:
default['stage_id'] = stage
return super(task, self).copy(cr, uid, id, default, context)
def _is_template(self, cr, uid, ids, field_name, arg, context=None):
res = {}
@ -1368,6 +1378,18 @@ class account_analytic_account(osv.osv):
raise osv.except_osv(_('Warning!'), _('Please delete the project linked with this account first.'))
return super(account_analytic_account, self).unlink(cr, uid, ids, *args, **kwargs)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if args is None:
args = []
if context is None:
context={}
if context.get('current_model') == 'project.project':
project_ids = self.search(cr, uid, args + [('name', operator, name)], limit=limit, context=context)
return self.name_get(cr, uid, project_ids, context=context)
return super(account_analytic_account, self).name_search(cr, uid, name, args=args, operator=operator, context=context, limit=limit)
class project_project(osv.osv):
_inherit = 'project.project'
_defaults = {

View File

@ -46,6 +46,23 @@
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">
<field eval="[(6,0,[])]" name="transition_ids"/>
<field eval="&quot;&quot;&quot;Procurement Task&quot;&quot;&quot;" name="name"/>

View File

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

View File

@ -41,7 +41,7 @@ class res_partner(osv.osv):
default.update({'purchase_order_ids': []})
super(res_partner, self).copy(cr, uid, id, default=default, context=context)
return super(res_partner, self).copy(cr, uid, id, default=default, context=context)
def _commercial_fields(self, cr, uid, context=None):
return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase']

View File

@ -24,7 +24,7 @@
<group name="shop">
<group>
<field name="payment_default_id"/>
<field domain="[('type','=','sale')]" name="pricelist_id" groups="product.group_sale_pricelist"/>
<field domain="[('type','=','sale')]" required="True" name="pricelist_id" groups="product.group_sale_pricelist"/>
</group>
<group>
<field name="project_id" groups="analytic.group_analytic_accounting"/>

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
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 = {
'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.'),

View File

@ -1910,7 +1910,8 @@ class stock_move(osv.osv):
"""
if not prod_id:
return {}
lang = False
user = self.pool.get('res.users').browse(cr, uid, uid)
lang = user and user.lang or False
if partner_id:
addr_rec = self.pool.get('res.partner').browse(cr, uid, partner_id)
if addr_rec:
@ -2053,7 +2054,10 @@ class stock_move(osv.osv):
ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
if picking:
# name of new picking according to its type
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
if ptype == 'internal':
new_pick_name = seq_obj.get(cr, uid,'stock.picking')
else :
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
# Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
@ -2940,8 +2944,8 @@ class stock_warehouse(osv.osv):
def _default_lot_output_id(self, cr, uid, context=None):
try:
lot_input_stock_model, lot_input_stock_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_output')
self.pool.get('stock.location').check_access_rule(cr, uid, [lot_input_stock_id], 'read', context=context)
lot_output_model, lot_output_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_output')
self.pool.get('stock.location').check_access_rule(cr, uid, [lot_output_id], 'read', context=context)
except (ValueError, orm.except_orm):
# the user does not have read access on the location or it does not exists
lot_output_id = False
@ -2999,6 +3003,18 @@ class stock_picking_in(osv.osv):
# instead of its own workflow (which is not existing)
return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""
return self.pool.get('stock.picking').message_post(*args, **kwargs)
def message_subscribe(self, *args, **kwargs):
"""Send the subscribe action on stock.picking model as it uses _name in request"""
return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
def message_unsubscribe(self, *args, **kwargs):
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
_columns = {
'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'state': fields.selection(
@ -3060,6 +3076,18 @@ class stock_picking_out(osv.osv):
# instead of its own workflow (which is not existing)
return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""
return self.pool.get('stock.picking').message_post(*args, **kwargs)
def message_subscribe(self, *args, **kwargs):
"""Send the subscribe action on stock.picking model as it uses _name in request"""
return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
def message_unsubscribe(self, *args, **kwargs):
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
_columns = {
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'state': fields.selection(

View File

@ -287,16 +287,6 @@
<field name="company_id" ref="base.main_company"/>
</record>
<record id="multicompany_user" model="res.users">
<field name="name">multicomp</field>
<field name="login">multicomp</field>
<field name="password">multicomp</field>
<field name="company_id" ref="res_company_2"/>
<field name="company_ids" eval="[(6,0,[ref('res_company_2')])]"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('stock.group_stock_manager')])]"/>
</record>
</data>
</openerp>

View File

@ -36,7 +36,13 @@ class TestStockMulticompany(common.TransactionCase):
self.stock_fill_inventory = self.registry('stock.fill.inventory')
self.stock_warehouse = self.registry('stock.warehouse')
model, self.multicompany_user_id = self.ir_model_data.get_object_reference(cr, uid, 'stock', 'multicompany_user')
model, group_user_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
model, group_stock_manager_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'group_stock_manager')
model, company_2_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'res_company_2')
self.multicompany_user_id = self.res_users.create(cr, uid,
{'name': 'multicomp', 'login': 'multicomp',
'groups_id': [(6, 0, [group_user_id, group_stock_manager_id])],
'company_id': company_2_id, 'company_ids': [(6,0,[company_2_id])]})
def test_00_multicompany_default_stock_move(self):
"""check no error on getting default stock.move values in multicompany setting"""

View File

@ -27,7 +27,7 @@ class change_standard_price(osv.osv_memory):
_name = "stock.change.standard.price"
_description = "Change Standard Price"
_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 "
"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."),

View File

@ -159,13 +159,15 @@ class stock_return_picking(osv.osv_memory):
returned_lines = 0
# Create new picking for returned products
seq_obj_name = 'stock.picking'
new_type = 'internal'
if pick.type =='out':
new_type = 'in'
seq_obj_name = 'stock.picking.in'
elif pick.type =='in':
new_type = 'out'
else:
new_type = 'internal'
seq_obj_name = 'stock.picking.' + new_type
seq_obj_name = 'stock.picking.out'
new_pick_name = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
new_picking = pick_obj.copy(cr, uid, pick.id, {
'name': _('%s-%s-return') % (new_pick_name, pick.name),