[MERGE] merge
bzr revid: mra@mra-laptop-20100713115253-xuan8ymwgv7p10q0
This commit is contained in:
@@ -183,7 +183,7 @@ class account_cash_statement(osv.osv):
|
||||
('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"),
|
||||
'total_entry_encoding':fields.function(_get_sum_entry_encoding, method=True, store=True, string="Cash Transaction", help="Total cash transactions"),
|
||||
'closing_date':fields.datetime("Closed On"),
|
||||
'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Opening Balance and Transactions"),
|
||||
'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Starting Balance and Cash Transactions"),
|
||||
'balance_end_cash': fields.function(_balance_end_cash, method=True, store=True, string='Balance', help="Closing balance based on cashBox"),
|
||||
'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'),
|
||||
'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'),
|
||||
|
||||
@@ -674,6 +674,7 @@ class account_move_line(osv.osv):
|
||||
account_id = line['account_id']['id']
|
||||
partner_id = (line['partner_id'] and line['partner_id']['id']) or False
|
||||
writeoff = debit - credit
|
||||
|
||||
# Ifdate_p in context => take this date
|
||||
if context.has_key('date_p') and context['date_p']:
|
||||
date=context['date_p']
|
||||
|
||||
@@ -2300,7 +2300,6 @@
|
||||
<field name="journal_id" on_change="onchange_journal_id(journal_id)" domain="[('type','=','cash')]" select="1" />
|
||||
<field name="user_id" select="1" readonly="1"/>
|
||||
<field name="period_id" select="1"/>
|
||||
<!-- <field name="balance_end_real"/>-->
|
||||
</group>
|
||||
|
||||
<notebook colspan="4">
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
<blockTable colWidths="62.0,62.0,22.0" style="Table_eclu_Taxes_Total">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_Bold_9">Net Total:</para>
|
||||
<para style="terp_default_9">Net Total:</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_untaxed) ]]</para>
|
||||
@@ -418,7 +418,7 @@
|
||||
<blockTable colWidths="63.0,61.0,23.0" style="Table_Taxes_Total">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_Bold_9">Taxes:</para>
|
||||
<para style="terp_default_9">Taxes:</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(o.amount_tax) ]]</para>
|
||||
|
||||
@@ -428,15 +428,17 @@ class account_voucher_line(osv.osv):
|
||||
'type': lambda *a: 'cr'
|
||||
}
|
||||
|
||||
def onchange_partner(self, cr, uid, ids, partner_id, ttype ,type1):
|
||||
vals = {}
|
||||
def onchange_partner(self, cr, uid, ids, partner_id, ttype ,type1, currency):
|
||||
currency_pool = self.pool.get('res.currency')
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid).company_id
|
||||
|
||||
vals = {
|
||||
'account_id': False,
|
||||
'type': False ,
|
||||
'amount': False
|
||||
}
|
||||
|
||||
if not partner_id:
|
||||
vals.update({
|
||||
'account_id': False,
|
||||
'type': False ,
|
||||
'amount': False
|
||||
})
|
||||
return {
|
||||
'value' : vals
|
||||
}
|
||||
@@ -466,6 +468,9 @@ class account_voucher_line(osv.osv):
|
||||
balance = partner.debit
|
||||
ttype = 'cr'
|
||||
|
||||
if company.currency_id != currency:
|
||||
balance = currency_pool.compute(cr, uid, company.currency_id.id, currency, balance)
|
||||
|
||||
vals.update({
|
||||
'account_id': account_id,
|
||||
'type': ttype,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<page string="Journal Entries">
|
||||
<field name="payment_ids" colspan="4" nolabel="1" height="250">
|
||||
<tree string="Voucher Lines" editable="top">
|
||||
<field name="partner_id" on_change="onchange_partner(partner_id,type,parent.type)"/>
|
||||
<field name="partner_id" on_change="onchange_partner(partner_id,type,parent.type, parent.currency_id)"/>
|
||||
<field name="account_id"/>
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<field name="payment_ids" position="replace">
|
||||
<field name="voucher_line_ids" default_get="{'lines': voucher_line_ids}" colspan="4" nolabel="1" height="275">
|
||||
<tree string="Voucher Lines" editable="top">
|
||||
<field name="partner_id" on_change="onchange_partner(partner_id, type, parent.type)"/>
|
||||
<field name="partner_id" on_change="onchange_partner(partner_id,type,parent.type, parent.currency_id)"/>
|
||||
<field name="account_id" on_change="onchange_line_account(account_id, type, parent.type)"/>
|
||||
<field name="name"/>
|
||||
<field name="invoice_id" on_change="onchange_invoice_id(invoice_id, parent.currency_id)" domain="[('partner_id','=',partner_id),('state','=','open'),('residual','>',0.0)]"/>
|
||||
|
||||
@@ -383,7 +383,7 @@ property or property parameter."),
|
||||
'rsvp': True,
|
||||
'cutype': 'individual',
|
||||
}
|
||||
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
raise osv.except_osv(_('Warning!'), _('Can not Duplicate'))
|
||||
|
||||
@@ -419,10 +419,14 @@ property or property parameter."),
|
||||
event.add('location').value = event_obj.location
|
||||
if event_obj.rrule:
|
||||
event.add('rrule').value = event_obj.rrule
|
||||
if event_obj.user_id:
|
||||
if event_obj.user_id or event_obj.organizer_id:
|
||||
event_org = event.add('organizer')
|
||||
event_org.params['CN'] = [event_obj.user_id.name]
|
||||
event_org.value = 'MAILTO:' + (event_obj.user_id.user_email or event_obj.user_id.name)
|
||||
organizer = event_obj.organizer_id
|
||||
if not organizer:
|
||||
organizer = event_obj.user_id
|
||||
event_org.params['CN'] = [organizer.name]
|
||||
event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name)
|
||||
|
||||
if event_obj.alarm_id:
|
||||
# computes alarm data
|
||||
valarm = event.add('valarm')
|
||||
@@ -455,14 +459,14 @@ property or property parameter."),
|
||||
attendee_add.value = 'MAILTO:' + (attendee.email or '')
|
||||
res = cal.serialize()
|
||||
return res
|
||||
|
||||
|
||||
def _send_mail(self, cr, uid, ids, mail_to, email_from=tools.config.get('email_from', False), context=None):
|
||||
"""
|
||||
Send mail for event invitation to event attendees.
|
||||
Send mail for event invitation to event attendees.
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of attendee’s IDs.
|
||||
@param email_from: Email address for user sending the mail
|
||||
@param email_from: Email address for user sending the mail
|
||||
@param context: A standard dictionary for contextual values
|
||||
@return: True
|
||||
"""
|
||||
@@ -474,7 +478,7 @@ property or property parameter."),
|
||||
sign = att.sent_by_uid and att.sent_by_uid.signature or ''
|
||||
sign = '<br>'.join(sign and sign.split('\n') or [])
|
||||
res_obj = att.ref
|
||||
sub = '[%s Invitation][%d] %s' % (company, att.id, res_obj.name)
|
||||
sub = res_obj.name
|
||||
att_infos = []
|
||||
other_invitaion_ids = self.search(cr, uid, [('ref', '=', res_obj._name + ',' + str(res_obj.id))])
|
||||
for att2 in self.browse(cr, uid, other_invitaion_ids):
|
||||
@@ -495,12 +499,12 @@ property or property parameter."),
|
||||
if mail_to and email_from:
|
||||
attach = self.get_ics_file(cr, uid, res_obj, context=context)
|
||||
tools.email_send(
|
||||
email_from,
|
||||
mail_to,
|
||||
sub,
|
||||
body,
|
||||
attach=attach and [('invitation.ics', attach)] or None,
|
||||
subtype='html',
|
||||
email_from,
|
||||
mail_to,
|
||||
sub,
|
||||
body,
|
||||
attach=attach and [('invitation.ics', attach)] or None,
|
||||
subtype='html',
|
||||
reply_to=email_from
|
||||
)
|
||||
return True
|
||||
@@ -528,31 +532,28 @@ property or property parameter."),
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of calendar attendee’s IDs
|
||||
@param *args: Get Tupple value
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
||||
|
||||
def do_accept(self, cr, uid, ids, context=None, *args):
|
||||
"""
|
||||
Update state of invitation as Accepted and
|
||||
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
|
||||
@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.
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param context: A standard dictionary for contextual values
|
||||
@return: True
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
for vals in self.browse(cr, uid, ids, context=context):
|
||||
#user = vals.user_id
|
||||
#if user:
|
||||
# mod_obj = self.pool.get(vals.ref._name)
|
||||
# if vals.ref:
|
||||
# if vals.ref.user_id.id != user.id:
|
||||
# defaults = {'user_id': user.id}
|
||||
# new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
|
||||
if vals.ref and vals.ref.user_id:
|
||||
mod_obj = self.pool.get(vals.ref._name)
|
||||
defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id}
|
||||
new_event = mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
|
||||
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
|
||||
|
||||
return True
|
||||
@@ -565,7 +566,8 @@ property or property parameter."),
|
||||
@param ids: List of calendar attendee’s IDs
|
||||
@param *args: Get Tupple value
|
||||
@param context: A standard dictionary for contextual values """
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
return self.write(cr, uid, ids, {'state': 'declined'}, context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
@@ -585,7 +587,6 @@ property or property parameter."),
|
||||
vals['cn'] = vals.get("cn")
|
||||
res = super(calendar_attendee, self).create(cr, uid, vals, context)
|
||||
return res
|
||||
|
||||
calendar_attendee()
|
||||
|
||||
class res_alarm(osv.osv):
|
||||
@@ -654,9 +655,9 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
alarm_ids = res_alarm_obj.search(cr, uid, domain, context=context)
|
||||
if not alarm_ids:
|
||||
val = {
|
||||
'trigger_duration': duration,
|
||||
'trigger_interval': interval,
|
||||
'trigger_occurs': occurs,
|
||||
'trigger_duration': duration,
|
||||
'trigger_interval': interval,
|
||||
'trigger_occurs': occurs,
|
||||
'trigger_related': related,
|
||||
'name': str(duration) + ' ' + str(interval) + ' ' + str(occurs)
|
||||
}
|
||||
@@ -724,35 +725,35 @@ class calendar_alarm(osv.osv):
|
||||
__attribute__ = {}
|
||||
|
||||
_columns = {
|
||||
'alarm_id': fields.many2one('res.alarm', 'Basic Alarm', ondelete='cascade'),
|
||||
'alarm_id': fields.many2one('res.alarm', 'Basic Alarm', ondelete='cascade'),
|
||||
'name': fields.char('Summary', size=124, help="""Contains the text to be \
|
||||
used as the message subject for email \
|
||||
or contains the text to be used for display"""),
|
||||
or contains the text to be used for display"""),
|
||||
'action': fields.selection([('audio', 'Audio'), ('display', 'Display'), \
|
||||
('procedure', 'Procedure'), ('email', 'Email') ], 'Action', \
|
||||
required=True, help="Defines the action to be invoked when an alarm is triggered"),
|
||||
required=True, help="Defines the action to be invoked when an alarm is triggered"),
|
||||
'description': fields.text('Description', help='Provides a more complete \
|
||||
description of the calendar component, than that \
|
||||
provided by the "SUMMARY" property'),
|
||||
provided by the "SUMMARY" property'),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'alarm_attendee_rel', \
|
||||
'alarm_id', 'attendee_id', 'Attendees', readonly=True),
|
||||
'alarm_id', 'attendee_id', 'Attendees', readonly=True),
|
||||
'attach': fields.binary('Attachment', help="""* Points to a sound resource,\
|
||||
which is rendered when the alarm is triggered for audio,
|
||||
* File which is intended to be sent as message attachments for email,
|
||||
* Points to a procedure resource, which is invoked when\
|
||||
the alarm is triggered for procedure."""),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'model_id': fields.many2one('ir.model', 'Model'),
|
||||
'user_id': fields.many2one('res.users', 'Owner'),
|
||||
'event_date': fields.datetime('Event Date'),
|
||||
'event_end_date': fields.datetime('Event End Date'),
|
||||
'trigger_date': fields.datetime('Trigger Date', readonly="True"),
|
||||
the alarm is triggered for procedure."""),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'model_id': fields.many2one('ir.model', 'Model'),
|
||||
'user_id': fields.many2one('res.users', 'Owner'),
|
||||
'event_date': fields.datetime('Event Date'),
|
||||
'event_end_date': fields.datetime('Event End Date'),
|
||||
'trigger_date': fields.datetime('Trigger Date', readonly="True"),
|
||||
'state':fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('run', 'Run'),
|
||||
('stop', 'Stop'),
|
||||
('done', 'Done'),
|
||||
], 'State', select=True, readonly=True),
|
||||
('draft', 'Draft'),
|
||||
('run', 'Run'),
|
||||
('stop', 'Stop'),
|
||||
('done', 'Done'),
|
||||
], 'State', select=True, readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
@@ -801,7 +802,7 @@ class calendar_alarm(osv.osv):
|
||||
current_datetime = datetime.now()
|
||||
request_obj = self.pool.get('res.request')
|
||||
alarm_ids = self.search(cr, uid, [('state', '!=', 'done')], context=context)
|
||||
|
||||
|
||||
mail_to = []
|
||||
|
||||
for alarm in self.browse(cr, uid, alarm_ids, context=context):
|
||||
@@ -916,10 +917,10 @@ class calendar_event(osv.osv):
|
||||
return {}
|
||||
event = self.browse(cr, uid, ids, context=context)[0]
|
||||
value = {
|
||||
'duration': 24
|
||||
'duration': 24
|
||||
}
|
||||
return {'value': value}
|
||||
|
||||
|
||||
def onchange_dates(self, cr, uid, ids, start_date, duration=False, end_date=False, allday=False, context=None):
|
||||
"""Returns duration and/or end date based on values passed
|
||||
@param self: The object pointer
|
||||
@@ -1082,11 +1083,11 @@ class calendar_event(osv.osv):
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'description': fields.text('Description', states={'done': [('readonly', True)]}),
|
||||
'class': fields.selection([('public', 'Public'), ('private', 'Private'), \
|
||||
('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
|
||||
'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
|
||||
('confidential', 'Confidential')], 'Mark as', states={'done': [('readonly', True)]}),
|
||||
'location': fields.char('Location', size=264, help="Location of Event", states={'done': [('readonly', True)]}),
|
||||
'show_as': fields.selection([('free', 'Free'), ('busy', 'Busy')], \
|
||||
'Show as', states={'done': [('readonly', True)]}),
|
||||
'base_calendar_url': fields.char('Caldav URL', size=264),
|
||||
'base_calendar_url': fields.char('Caldav URL', size=264),
|
||||
'state': fields.selection([('tentative', 'Tentative'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('cancelled', 'Cancelled')], 'State', readonly=True),
|
||||
@@ -1110,6 +1111,7 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
|
||||
'vtimezone': fields.related('user_id', 'context_tz', type='char', size=24, \
|
||||
string='Timezone', store=True),
|
||||
'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
|
||||
'organizer_id': fields.many2one('res.users', 'Organizer', states={'done': [('readonly', True)]}),
|
||||
'freq': fields.selection([('None', 'No Repeat'), \
|
||||
('secondly', 'Secondly'), \
|
||||
('minutely', 'Minutely'), \
|
||||
@@ -1136,25 +1138,27 @@ e.g.: Every other month on the last Sunday of the month for 10 occurrences:\
|
||||
('SU', 'Sunday')], 'Weekday'),
|
||||
'byday': fields.selection([('1', 'First'), ('2', 'Second'), \
|
||||
('3', 'Third'), ('4', 'Fourth'), \
|
||||
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
|
||||
'month_list': fields.selection(months.items(), 'Month'),
|
||||
'end_date': fields.date('Repeat Until'),
|
||||
('5', 'Fifth'), ('-1', 'Last')], 'By day'),
|
||||
'month_list': fields.selection(months.items(), 'Month'),
|
||||
'end_date': fields.date('Repeat Until'),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', 'event_attendee_rel', \
|
||||
'event_id', 'attendee_id', 'Attendees'),
|
||||
'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
|
||||
'event_id', 'attendee_id', 'Attendees'),
|
||||
'allday': fields.boolean('All Day', states={'done': [('readonly', True)]}),
|
||||
'active': fields.boolean('Active', help="If the active field is set to \
|
||||
true, it will allow you to hide the event alarm information without removing it.")
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': 'tentative',
|
||||
'state': 'tentative',
|
||||
'class': 'public',
|
||||
'show_as': 'busy',
|
||||
'freq': 'None',
|
||||
'select1': 'date',
|
||||
'interval': 1,
|
||||
'active': 1,
|
||||
}
|
||||
'user_id': lambda self, cr, uid, ctx: uid,
|
||||
'organizer_id': lambda self, cr, uid, ctx: uid,
|
||||
}
|
||||
|
||||
def open_event(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
@@ -1183,26 +1187,26 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
id4 = data_obj.browse(cr, uid, id4, context=context).res_id
|
||||
for id in ids:
|
||||
value = {
|
||||
'name': _('Event'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form,tree',
|
||||
'res_model': 'calendar.event',
|
||||
'view_id': False,
|
||||
'views': [(id2, 'form'), (id3, 'tree'), (id4, 'calendar')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_id': base_calendar_id2real_id(id),
|
||||
'name': _('Event'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form,tree',
|
||||
'res_model': 'calendar.event',
|
||||
'view_id': False,
|
||||
'views': [(id2, 'form'), (id3, 'tree'), (id4, 'calendar')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_id': base_calendar_id2real_id(id),
|
||||
'nodestroy': True
|
||||
}
|
||||
|
||||
return value
|
||||
|
||||
def modify_this(self, cr, uid, event_id, defaults, real_date, context=None, *args):
|
||||
"""Modifies only one event record out of virtual recurrent events
|
||||
"""Modifies only one event record out of virtual recurrent events
|
||||
and creates new event as a specific instance of a Recurring Event",
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param event_id: Id of Recurring Event
|
||||
@param event_id: Id of Recurring Event
|
||||
@param real_date: Date of event recurrence that is being modified
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param *args: Get Tupple Value
|
||||
@@ -1225,7 +1229,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
|
||||
def modify_all(self, cr, uid, event_ids, defaults, context=None, *args):
|
||||
"""
|
||||
Modifies the recurring event
|
||||
Modifies the recurring event
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param event_ids: List of crm meeting’s IDs.
|
||||
@@ -1252,7 +1256,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
|
||||
def get_recurrent_ids(self, cr, uid, select, base_start_date, base_until_date, limit=100):
|
||||
"""Gives virtual event ids for recurring events based on value of Recurrence Rule
|
||||
This method gives ids of dates that comes between start date and end date of calendar views
|
||||
This method gives ids of dates that comes between start date and end date of calendar views
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@@ -1418,8 +1422,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
until_date = arg[2]
|
||||
res = super(calendar_event, self).search(cr, uid, args_without_date, \
|
||||
offset, limit, order, context, count)
|
||||
#Search Event ID which are invitted
|
||||
|
||||
|
||||
return self.get_recurrent_ids(cr, uid, res, start_date, until_date, limit)
|
||||
|
||||
|
||||
@@ -1558,7 +1561,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
event_id = [int(event_id)]
|
||||
for record in self.read(cr, uid, event_id, ['date', 'rrule', 'exdate']):
|
||||
if record['rrule']:
|
||||
# Remove one of the recurrent event
|
||||
# Remove one of the recurrent event
|
||||
date_new = time.strftime("%Y-%m-%d %H:%M:%S", \
|
||||
time.strptime(date_new, "%Y%m%d%H%M%S"))
|
||||
exdate = (record['exdate'] and (record['exdate'] + ',') or '') + ''.join((re.compile('\d')).findall(date_new)) + 'Z'
|
||||
@@ -1584,7 +1587,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
||||
return res
|
||||
|
||||
|
||||
def do_tentative(self, cr, uid, ids, context=None, *args):
|
||||
""" Makes event invitation as Tentative
|
||||
@param self: The object pointer
|
||||
@@ -1592,10 +1595,10 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Event IDs
|
||||
@param *args: Get Tupple value
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state': 'tentative'}, context)
|
||||
|
||||
|
||||
def do_cancel(self, cr, uid, ids, context=None, *args):
|
||||
""" Makes event invitation as Tentative
|
||||
@param self: The object pointer
|
||||
@@ -1603,7 +1606,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Event IDs
|
||||
@param *args: Get Tupple value
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state': 'cancelled'}, context)
|
||||
|
||||
@@ -1614,7 +1617,7 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of Event IDs
|
||||
@param *args: Get Tupple value
|
||||
@param context: A standard dictionary for contextual values
|
||||
@param context: A standard dictionary for contextual values
|
||||
"""
|
||||
return self.write(cr, uid, ids, {'state': 'confirmed'}, context)
|
||||
|
||||
@@ -1758,9 +1761,9 @@ class ir_model(osv.osv):
|
||||
|
||||
_inherit = 'ir.model'
|
||||
|
||||
def read(self, cr, uid, ids, fields=None, context=None,
|
||||
def read(self, cr, uid, ids, fields=None, context=None,
|
||||
load='_classic_read'):
|
||||
"""
|
||||
"""
|
||||
Overrides orm read method.
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@@ -1807,7 +1810,7 @@ class res_users(osv.osv):
|
||||
_inherit = 'res.users'
|
||||
|
||||
def _get_user_avail(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
"""
|
||||
Get User Availability
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@@ -1838,7 +1841,7 @@ class res_users(osv.osv):
|
||||
return res
|
||||
|
||||
def _get_user_avail_fun(self, cr, uid, ids, name, args, context=None):
|
||||
"""
|
||||
"""
|
||||
Get User Availability Function
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
<field name="currency" widget="selection"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group colspan="2" groups="base.group_extended">
|
||||
<separator string="Report Information" colspan="4"/>
|
||||
<field name="rml_header1" colspan="5"/>
|
||||
<field name="rml_footer1" colspan="5"/>
|
||||
<field name="rml_footer2" colspan="5"/>
|
||||
<group colspan="2" groups="base.group_extended" >
|
||||
<!-- <separator string="Report Information" colspan="4" />-->
|
||||
<field name="rml_header1" colspan="5" invisible="1"/>
|
||||
<field name="rml_footer1" colspan="5" invisible="1"/>
|
||||
<field name="rml_footer2" colspan="5" invisible="1"/>
|
||||
|
||||
<separator colspan="4"
|
||||
string="Your Logo - Use a size of about 450x150 pixels."/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
|
||||
<record model="document.directory" id="document.dir_calendars">
|
||||
<field name="name">Calendars</field>
|
||||
<field name="calendar_collection">True</field>
|
||||
@@ -14,6 +14,11 @@
|
||||
<field name="type">vevent</field>
|
||||
</record>
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_event_organizer">
|
||||
<field name="name">organizer</field>
|
||||
<field name="type">vevent</field>
|
||||
</record>
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_event_uid">
|
||||
<field name="name">uid</field>
|
||||
<field name="type">vevent</field>
|
||||
@@ -58,12 +63,12 @@
|
||||
<field name="name">valarm</field>
|
||||
<field name="type">vevent</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_event_vtimezone">
|
||||
<field name="name">vtimezone</field>
|
||||
<field name="type">vevent</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_event_priority">
|
||||
<field name="name">priority</field>
|
||||
<field name="type">vevent</field>
|
||||
@@ -181,12 +186,12 @@
|
||||
<field name="name">seq</field>
|
||||
<field name="type">vtodo</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_todo_vtimezone">
|
||||
<field name="name">vtimezone</field>
|
||||
<field name="type">vtodo</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.attributes" id="field_todo_url">
|
||||
<field name="name">url</field>
|
||||
<field name="type">vtodo</field>
|
||||
|
||||
+33
-20
@@ -228,6 +228,8 @@ class CalDAV(object):
|
||||
|
||||
att_data = []
|
||||
for cal_data in child.getChildren():
|
||||
if cal_data.name.lower() == 'organizer':
|
||||
self.ical_set(cal_data.name.lower(), {'name':cal_data.params['CN']}, 'value')
|
||||
if cal_data.name.lower() == 'attendee':
|
||||
ctx = context.copy()
|
||||
if cal_children:
|
||||
@@ -266,7 +268,7 @@ class CalDAV(object):
|
||||
if not datas:
|
||||
return
|
||||
timezones = []
|
||||
for data in datas:
|
||||
for data in datas:
|
||||
tzval = None
|
||||
vevent = ical.add(name)
|
||||
for field in self.__attribute__.keys():
|
||||
@@ -307,6 +309,13 @@ class CalDAV(object):
|
||||
ical = tz_obj.export_cal(cr, uid, None, \
|
||||
data[map_field], ical, context=context)
|
||||
timezones.append(data[map_field])
|
||||
elif field == 'organizer' and data[map_field]:
|
||||
event_org = vevent.add('organizer')
|
||||
organizer_id = data[map_field][0]
|
||||
user_obj = self.pool.get('res.users')
|
||||
organizer = user_obj.browse(cr, uid, organizer_id, context=context)
|
||||
event_org.params['CN'] = [organizer.name]
|
||||
event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name)
|
||||
elif data[map_field]:
|
||||
if map_type in ("char", "text"):
|
||||
if field in ('exdate'):
|
||||
@@ -414,7 +423,7 @@ class CalDAV(object):
|
||||
return res
|
||||
|
||||
class Calendar(CalDAV, osv.osv):
|
||||
_name = 'basic.calendar'
|
||||
_name = 'basic.calendar'
|
||||
_calname = 'calendar'
|
||||
|
||||
__attribute__ = {
|
||||
@@ -431,13 +440,13 @@ class Calendar(CalDAV, osv.osv):
|
||||
'vtimezone': None, # Use: O-n, Type: Collection of Timezone class
|
||||
}
|
||||
_columns = {
|
||||
'name': fields.char("Name", size=64),
|
||||
'name': fields.char("Name", size=64),
|
||||
'user_id': fields.many2one('res.users', 'Owner'),
|
||||
'collection_id': fields.many2one('document.directory', 'Collection', \
|
||||
required=True),
|
||||
'type': fields.selection([('vevent', 'Event'), ('vtodo', 'TODO')], \
|
||||
string="Type", size=64),
|
||||
'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'),
|
||||
'line_ids': fields.one2many('basic.calendar.lines', 'calendar_id', 'Calendar Lines'),
|
||||
'create_date': fields.datetime('Created Date'),
|
||||
'write_date': fields.datetime('Modifided Date'),
|
||||
}
|
||||
@@ -448,8 +457,8 @@ class Calendar(CalDAV, osv.osv):
|
||||
if not domain:
|
||||
domain = []
|
||||
res = []
|
||||
ctx_res_id = context.get('res_id', None)
|
||||
ctx_model = context.get('model', None)
|
||||
ctx_res_id = context.get('res_id', None)
|
||||
ctx_model = context.get('model', None)
|
||||
for cal in self.browse(cr, uid, ids):
|
||||
for line in cal.line_ids:
|
||||
if ctx_model and ctx_model != line.object_id.model:
|
||||
@@ -458,13 +467,13 @@ class Calendar(CalDAV, osv.osv):
|
||||
continue
|
||||
line_domain = eval(line.domain)
|
||||
line_domain += domain
|
||||
if ctx_res_id:
|
||||
if ctx_res_id:
|
||||
line_domain += [('id','=',ctx_res_id)]
|
||||
mod_obj = self.pool.get(line.object_id.model)
|
||||
data_ids = mod_obj.search(cr, uid, line_domain, context=context)
|
||||
data_ids = mod_obj.search(cr, uid, line_domain, context=context)
|
||||
for data in mod_obj.browse(cr, uid, data_ids, context):
|
||||
ctx = parent and parent.context or None
|
||||
node = res_node_calendar('%s' %data.id, parent, ctx, data, line.object_id.model, data.id)
|
||||
node = res_node_calendar('%s' %data.id, parent, ctx, data, line.object_id.model, data.id)
|
||||
res.append(node)
|
||||
return res
|
||||
|
||||
@@ -478,8 +487,8 @@ class Calendar(CalDAV, osv.osv):
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
ctx_model = context.get('model', None)
|
||||
ctx_res_id = context.get('res_id', None)
|
||||
ctx_model = context.get('model', None)
|
||||
ctx_res_id = context.get('res_id', None)
|
||||
ical = vobject.iCalendar()
|
||||
for cal in self.browse(cr, uid, ids):
|
||||
for line in cal.line_ids:
|
||||
@@ -488,7 +497,7 @@ class Calendar(CalDAV, osv.osv):
|
||||
if line.name in ('valarm', 'attendee'):
|
||||
continue
|
||||
domain = eval(line.domain)
|
||||
if ctx_res_id:
|
||||
if ctx_res_id:
|
||||
domain += [('id','=',ctx_res_id)]
|
||||
mod_obj = self.pool.get(line.object_id.model)
|
||||
data_ids = mod_obj.search(cr, uid, domain, context=context)
|
||||
@@ -496,7 +505,7 @@ class Calendar(CalDAV, osv.osv):
|
||||
context.update({'model': line.object_id.model,
|
||||
'calendar_id': cal.id
|
||||
})
|
||||
self.__attribute__ = get_attribute_mapping(cr, uid, line.name, context)
|
||||
self.__attribute__ = get_attribute_mapping(cr, uid, line.name, context)
|
||||
self.create_ics(cr, uid, datas, line.name, ical, context=context)
|
||||
return ical.serialize()
|
||||
|
||||
@@ -511,16 +520,18 @@ class Calendar(CalDAV, osv.osv):
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
vals = []
|
||||
vals = []
|
||||
ical_data = base64.decodestring(content)
|
||||
parsedCal = vobject.readOne(ical_data)
|
||||
if not data_id:
|
||||
data_id = self.search(cr, uid, [])[0]
|
||||
data_id = self.search(cr, uid, [])[0]
|
||||
cal = self.browse(cr, uid, data_id, context=context)
|
||||
cal_children = {}
|
||||
count = 0
|
||||
for line in cal.line_ids:
|
||||
cal_children[line.name] = line.object_id.model
|
||||
objs = []
|
||||
checked = True
|
||||
for child in parsedCal.getChildren():
|
||||
if child.name.lower() in cal_children:
|
||||
context.update({'model': cal_children[child.name.lower()],
|
||||
@@ -528,12 +539,14 @@ class Calendar(CalDAV, osv.osv):
|
||||
})
|
||||
self.__attribute__ = get_attribute_mapping(cr, uid, child.name.lower(), context=context)
|
||||
val = self.parse_ics(cr, uid, child, cal_children=cal_children, context=context)
|
||||
val.update({'user_id': uid})
|
||||
vals.append(val)
|
||||
obj = self.pool.get(cal_children[child.name.lower()])
|
||||
if hasattr(obj, 'check_import'):
|
||||
obj.check_import(cr, uid, vals, context=context)
|
||||
else:
|
||||
objs.append(cal_children[child.name.lower()])
|
||||
for obj_name in list(set(objs)):
|
||||
obj = self.pool.get(obj_name)
|
||||
if hasattr(obj, 'check_import'):
|
||||
obj.check_import(cr, uid, vals, context=context)
|
||||
checked = True
|
||||
if not checked:
|
||||
self.check_import(cr, uid, vals, context=context)
|
||||
return {}
|
||||
Calendar()
|
||||
|
||||
@@ -29,21 +29,69 @@
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crm_case_my_open_oppor">
|
||||
<field name="name">My Open Opportunities</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Opportunities" colors="blue:state=='pending';grey:state in ('cancel', 'done');red:date_deadline and (date_deadline < current_date)">
|
||||
<field name="name" string="Opportunity"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="stage_id"/>
|
||||
<button name="stage_previous" string="Previous Stage"
|
||||
states="open,pending" type="object" icon="gtk-go-back" />
|
||||
<button name="stage_next" string="Next Stage"
|
||||
states="open,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<field name="planned_revenue" sum="Total of Planned Revenue"/>
|
||||
<field name="probability" widget="progressbar" avg="Avg. of Probability"/>
|
||||
<field name="date_deadline" invisible="1"/>
|
||||
<field name="state"/>
|
||||
<button name="case_open" string="Open"
|
||||
states="draft,pending" type="object"
|
||||
icon="gtk-go-forward" />
|
||||
<button name="case_pending" string="Pending"
|
||||
states="open,draft" type="object"
|
||||
icon="gtk-media-pause" />
|
||||
<button name="case_mark_lost" string="Lost"
|
||||
states="open,pending" type="object"
|
||||
icon="gtk-cancel" />
|
||||
<button name="case_close" string="Won"
|
||||
states="open,draft,pending" type="object"
|
||||
icon="gtk-apply" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="act_my_oppor">
|
||||
<field name="name">My Open Opportunities</field>
|
||||
<field name="res_model">crm.lead</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="crm.crm_case_tree_view_oppor"/>
|
||||
<field name="domain">[('user_id','=',uid),('state','=','open'), ('type', '=', 'opportunity')]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="act_my_oppor_tree_view">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_id" ref="crm_case_my_open_oppor"/>
|
||||
<field name="act_window_id" ref="act_my_oppor"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="act_my_oppor_form_view">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="crm_case_form_view_oppor"/>
|
||||
<field name="act_window_id" ref="act_my_oppor"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="act_my_meetings">
|
||||
<field name="res_model">crm.meeting</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="crm.crm_case_tree_view_meet"/>
|
||||
<field name="domain">[('user_id','=',uid),('state','!=','cancel'),('date','ilike',time.strftime("%Y-%m"))]</field>
|
||||
<field name="domain">[('user_id','=',uid),('state','not in',('cancel','done'))]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="act_my_oppor_stage">
|
||||
@@ -59,7 +107,7 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,tree,form</field>
|
||||
<field name="view_id" ref="view_crm_opportunity_user_graph1"/>
|
||||
<field name="domain">['&', ('state', '=', 'done') , '&', ('create_date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%Y-%m-%d')), ('type', '=', 'opportunity')]</field>
|
||||
<field name="domain">['&', ('user_id', '=', uid),'&', ('state', '=', 'done') , '&', ('create_date','>',(datetime.date.today()-datetime.timedelta(days=365)).strftime('%Y-%m-%d')), ('type', '=', 'opportunity')]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="board_crm_form">
|
||||
@@ -84,11 +132,11 @@
|
||||
</child1>
|
||||
<child2>
|
||||
<action
|
||||
string="Planned Revenues by Stage"
|
||||
string="My Planned Revenues by Stage"
|
||||
name="%(act_my_oppor_stage)d"
|
||||
colspan="4"/>
|
||||
<action
|
||||
string="Win/Lost Ratio for the Last Year"
|
||||
string="My Win/Lost Ratio for the Last Year"
|
||||
name="%(act_sales_pipeline)d"
|
||||
colspan="4"/>
|
||||
</child2>
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Assignment"/>
|
||||
<field name="user_id" />
|
||||
<field name="organizer_id" groups="base.group_extended"/>
|
||||
<field name="section_id" widget="selection"
|
||||
groups="base.group_extended"/>
|
||||
</group><group col="2" colspan="2">
|
||||
@@ -154,7 +155,9 @@
|
||||
<field name="attendee_ids" colspan="4"
|
||||
nolabel="1" widget="one2many" mode="tree,form">
|
||||
<tree string="Invitation details" editable="top">
|
||||
<field name="email" />
|
||||
<field name="sent_by_uid" string="From"/>
|
||||
<field name="user_id" string="To"/>
|
||||
<field name="email" string="Mail TO"/>
|
||||
<field name="role" select="1" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
@@ -342,7 +345,7 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -24,6 +24,7 @@ from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import crm
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
class crm_phonecall(osv.osv, crm_case):
|
||||
""" Phonecall Cases """
|
||||
@@ -65,7 +66,7 @@ class crm_phonecall(osv.osv, crm_case):
|
||||
('object_id.model', '=', 'crm.phonecall')]"),
|
||||
'date_open': fields.datetime('Opened', readonly=True),
|
||||
# phonecall fields
|
||||
'duration': fields.float('Duration'),
|
||||
'duration': fields.float('Duration', help="Duration in Minutes"),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.phonecall')]"),
|
||||
@@ -113,10 +114,29 @@ class crm_phonecall(osv.osv, crm_case):
|
||||
@param ids: List of case Ids
|
||||
@param *args: Tuple Value for additional Params
|
||||
"""
|
||||
res = super(crm_phonecall, self).case_close(cr, uid, ids, args)
|
||||
self.write(cr, uid, ids, {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
for phone in self.browse(cr, uid, ids):
|
||||
phone_id= phone.id
|
||||
data = {'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')}
|
||||
if phone.duration <=0:
|
||||
duration = datetime.now() - datetime.strptime(phone.date, '%Y-%m-%d %H:%M:%S')
|
||||
data.update({'duration': duration.seconds/float(60)})
|
||||
res = super(crm_phonecall, self).case_close(cr, uid, [phone_id], args)
|
||||
self.write(cr, uid, ids, data)
|
||||
return res
|
||||
|
||||
def case_reset(self, cr, uid, ids, *args):
|
||||
"""Resets case as draft
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@param ids: List of case Ids
|
||||
@param *args: Tuple Value for additional Params
|
||||
"""
|
||||
res = super(crm_phonecall, self).case_reset(cr, uid, ids, args)
|
||||
self.write(cr, uid, ids, {'duration': 0.0})
|
||||
return res
|
||||
|
||||
|
||||
def case_open(self, cr, uid, ids, *args):
|
||||
"""Overrides cancel for crm_case for setting Open Date
|
||||
@param self: The object pointer
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- Event Attribute mapping for Calendar-->
|
||||
|
||||
@@ -22,13 +22,20 @@
|
||||
<field name="calendar_id" ref="caldav.basic_calendar1" />
|
||||
<field name="object_id" search="[('model','=','calendar.alarm')]" />
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.lines" id="base_calendar.calendar_lines_attendee">
|
||||
<field name="name">attendee</field>
|
||||
<field name="calendar_id" ref="caldav.basic_calendar1" />
|
||||
<field name="object_id" search="[('model','=','calendar.attendee')]" />
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.fields" id="map_event_0">
|
||||
<field name="name" ref="caldav.field_event_organizer"/>
|
||||
<field name="type_id" ref="base_calendar.calendar_lines_event" />
|
||||
<field name="field_id" search="[('name','=','organizer_id'),('model_id.model','=','calendar.event')]" />
|
||||
<field name="fn">field</field>
|
||||
</record>
|
||||
|
||||
<record model="basic.calendar.fields" id="map_event_1">
|
||||
<field name="name" ref="caldav.field_event_uid"/>
|
||||
<field name="type_id" ref="base_calendar.calendar_lines_event" />
|
||||
@@ -42,7 +49,7 @@
|
||||
<field name="field_id" search="[('name','=','recurrent_id'),('model_id.model','=','calendar.event')]" />
|
||||
<field name="fn">field</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="basic.calendar.fields" id="map_event_3">
|
||||
<field name="name" ref="caldav.field_event_vtimezone"/>
|
||||
<field name="type_id" ref="base_calendar.calendar_lines_event" />
|
||||
@@ -55,7 +62,7 @@
|
||||
<field name="type_id" ref="base_calendar.calendar_lines_event" />
|
||||
<field name="field_id" search="[('name','=','attendee_ids'),('model_id.model','=','crm.meeting')]" />
|
||||
<field name="fn">field</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<record model="basic.calendar.fields" id="map_event_5">
|
||||
<field name="name" ref="caldav.field_event_rrule"/>
|
||||
@@ -154,7 +161,7 @@
|
||||
<field name="type_id" ref="base_calendar.calendar_lines_event" />
|
||||
<field name="field_id" search="[('name','=','name'),('model_id.model','=','calendar.event')]" />
|
||||
<field name="fn">field</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
@@ -313,7 +320,7 @@
|
||||
<field name="fn">field</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -45,8 +45,9 @@
|
||||
-
|
||||
Attach a pdf file in "My document"
|
||||
-
|
||||
!python {model: ir.attachment}: |
|
||||
!python {model: 'ir.attachment'}: |
|
||||
import tools
|
||||
import base64
|
||||
file = open(tools.config['addons_path'] + '/document/test/partner.pdf')
|
||||
id = self.write(cr, uid, [ref("document_1")], {'datas' : base64.encodestring(file.read())}, context)
|
||||
pdf_file = open(tools.config['addons_path'] + '/document/test/partner.pdf')
|
||||
self.write(cr, uid, [ref("document_1")], {'datas_fname': 'partner.pdf', 'datas' : base64.encodestring(pdf_file.read())}, context)
|
||||
|
||||
|
||||
+12
-11
@@ -53,21 +53,22 @@
|
||||
<field name="product_id" on_change="onchange_product(product_id)"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="General">
|
||||
<page string="Event Information">
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="unit_price"/>
|
||||
<field name="currency_id"/>
|
||||
<separator string="Speaker Information" colspan="4"/>
|
||||
<field name="main_speaker_id" domain="[('speaker','=',True)]"/>
|
||||
<field name="address_id"/>
|
||||
<field name="speaker_ids" domain="[('speaker','=',True)]" colspan="4"/>
|
||||
<field name="country_id" />
|
||||
<field name="speaker_confirmed"/>
|
||||
<field name="language"/>
|
||||
<separator string="Event description" colspan="4"/>
|
||||
<field name="parent_id" domain="[('parent_id','child_of','Event')]"/>
|
||||
<field name="active"/>
|
||||
<field name="register_min"/>
|
||||
<field name="register_max"/>
|
||||
<field name="parent_id" domain="[('parent_id','child_of','Event')]"/>
|
||||
<field name="active"/>
|
||||
<separator string="Location" colspan="4"/>
|
||||
<field name="country_id" />
|
||||
<field name="language"/>
|
||||
<field name="address_id"/>
|
||||
<separator string="Speaker Information" colspan="4"/>
|
||||
<field name="main_speaker_id" domain="[('speaker','=',True)]"/>
|
||||
<field name="speaker_confirmed"/>
|
||||
<field name="speaker_ids" domain="[('speaker','=',True)]" colspan="4"/>
|
||||
<newline/>
|
||||
<field name="state" select="1"/>
|
||||
<group col="4" colspan="2">
|
||||
|
||||
@@ -30,7 +30,13 @@ class project_task(osv.osv):
|
||||
'create_date': fields.datetime('Create Date'),
|
||||
'attendee_ids': fields.many2many('calendar.attendee', \
|
||||
'task_attendee_rel', 'task_id', 'attendee_id', 'Attendees'),
|
||||
}
|
||||
'state': fields.selection([('draft', 'Draft'),('open', 'In Progress'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'State', readonly=True, required=True,
|
||||
help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\
|
||||
\n If the task is over, the states is set to \'Done\'.'),
|
||||
}
|
||||
_defaults = {
|
||||
'state': 'draft',
|
||||
}
|
||||
|
||||
def import_cal(self, cr, uid, data, data_id=None, context=None):
|
||||
todo_obj = self.pool.get('basic.calendar.todo')
|
||||
@@ -43,7 +49,7 @@ class project_task(osv.osv):
|
||||
ids = []
|
||||
for val in vals:
|
||||
obj_tm = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
if not val.has_key('planned_hours'):
|
||||
if not val.get('planned_hours', False):
|
||||
# 'Computes duration' in days
|
||||
plan = 0.0
|
||||
if val.get('date') and val.get('date_deadline'):
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<data noupdate="1">
|
||||
|
||||
<record model="basic.calendar" id="caldav.basic_calendar2">
|
||||
<field name="name">Todo</field>
|
||||
<field name="name">Tasks</field>
|
||||
<field name="collection_id" ref="document.dir_calendars"></field>
|
||||
<field name="type">vtodo</field>
|
||||
</record>
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
<field name="attendee_ids" colspan="4"
|
||||
nolabel="1" widget="one2many" mode="tree,form">
|
||||
<tree string="Assignees details" editable="top">
|
||||
<field name="email" />
|
||||
<field name="sent_by_uid" string="From"/>
|
||||
<field name="user_id" string="To"/>
|
||||
<field name="email" string="Mail TO"/>
|
||||
<field name="role" select="1" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
|
||||
+2
-2
@@ -785,8 +785,8 @@ class sale_order_line(osv.osv):
|
||||
res = {}
|
||||
context = context or {}
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
price = line.price_unit * line.product_uom_qty * (1 - (line.discount or 0.0) / 100.0)
|
||||
taxes = tax_obj.compute_all(cr, uid, line.tax_id, line.price_unit, line.product_uom_qty)
|
||||
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
|
||||
taxes = tax_obj.compute_all(cr, uid, line.tax_id, price, line.product_uom_qty, line.order_id.partner_invoice_id.id, line.product_id, line.order_id.partner_id)
|
||||
cur = line.order_id.pricelist_id.currency_id
|
||||
res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
|
||||
return res
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_sale_order_make_invoice" model="ir.ui.view">
|
||||
<record id="view_sale_order_make_invoice" model="ir.ui.view">
|
||||
<field name="name">Create invoices</field>
|
||||
<field name="model">sale.make.invoice</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create invoices">
|
||||
<separator colspan="4" string="Do you really want to create the invoice(s) ?" />
|
||||
<field name="grouped"/>
|
||||
<newline/>
|
||||
<field name="invoice_date"/>
|
||||
<separator string="" colspan="6"/>
|
||||
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button name="make_invoices" string="Create Invoices" type="object" icon="gtk-ok"/>
|
||||
</form>
|
||||
<form string="Create invoices">
|
||||
<separator colspan="4" string="Do you really want to create the invoice(s) ?" />
|
||||
<field name="grouped"/>
|
||||
<newline/>
|
||||
<field name="invoice_date"/>
|
||||
<separator string="" colspan="6"/>
|
||||
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button name="make_invoices" string="Create Invoices" type="object" icon="gtk-ok"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</record>
|
||||
|
||||
<act_window name="Make Invoices"
|
||||
res_model="sale.make.invoice"
|
||||
src_model="sale.order"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
<record id="action_sale_order_make_invoice" model="ir.actions.act_window">
|
||||
<field name="name">Make Invoices</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sale.make.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Make Invoices"
|
||||
res_model="sale.make.invoice"
|
||||
src_model="sale.order"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_view_sale_order_make_invoice"/>
|
||||
id="action_view_sale_order_make_invoice"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
from mx.DateTime import now
|
||||
import time
|
||||
import decimal_precision as dp
|
||||
|
||||
class crm_make_sale(osv.osv_memory):
|
||||
""" Make sale order for crm """
|
||||
@@ -100,7 +102,6 @@ class crm_make_sale(osv.osv_memory):
|
||||
vals = {
|
||||
'origin': 'Opportunity:%s' % str(case.id),
|
||||
'section_id': case.section_id and case.section_id.id or False,
|
||||
'picking_policy': make.picking_policy,
|
||||
'shop_id': make.shop_id.id,
|
||||
'partner_id': partner_id,
|
||||
'pricelist_id': pricelist,
|
||||
@@ -119,14 +120,16 @@ class crm_make_sale(osv.osv_memory):
|
||||
if make.analytic_account.id:
|
||||
vals['project_id'] = make.analytic_account.id
|
||||
new_id = sale_obj.create(cr, uid, vals)
|
||||
for product_id in make.product_ids:
|
||||
for line in make.sale_order_line:
|
||||
value = sale_line_obj.product_id_change(cr, uid, [], pricelist,
|
||||
product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
|
||||
value['product_id'] = product_id.id
|
||||
line.product_id.id, qty=1, partner_id=partner_id, fiscal_position=fpos)['value']
|
||||
value['product_id'] =line.product_id.id
|
||||
value['order_id'] = new_id
|
||||
value['tax_id'] = [(6,0,value['tax_id'])]
|
||||
value['tax_id'] = [(6,0,line['tax_id'])]
|
||||
value['product_uom_qty']=line.product_uom_qty
|
||||
value['discount']=line.discount
|
||||
value['product_uom']=line.product_uom.id
|
||||
sale_line_obj.create(cr, uid, value)
|
||||
|
||||
case_obj.write(cr, uid, [case.id], {'ref': 'sale.order,%s' % new_id})
|
||||
new_ids.append(new_id)
|
||||
message = _('Opportunity ') + " '" + case.name + "' "+ _("is converted to Sales Quotation.")
|
||||
@@ -163,10 +166,7 @@ class crm_make_sale(osv.osv_memory):
|
||||
_columns = {
|
||||
'shop_id': fields.many2one('sale.shop', 'Shop', required=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Customer', required=True, help='Use this partner if there is no partner on the Opportunity'),
|
||||
'picking_policy': fields.selection([('direct','Partial Delivery'),
|
||||
('one','Complete Delivery')], 'Picking Policy', required=True),
|
||||
'product_ids': fields.many2many('product.product', 'product_sale_rel',\
|
||||
'sale_id', 'product_id', 'Products'),
|
||||
'sale_order_line': fields.one2many('sale.order.make.line', 'order_line', 'Product Line', readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'analytic_account': fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||
'close': fields.boolean('Close Case', help='Check this to close the case after having created the sale order.'),
|
||||
}
|
||||
@@ -174,6 +174,160 @@ class crm_make_sale(osv.osv_memory):
|
||||
'partner_id': _selectPartner,
|
||||
'close': 1
|
||||
}
|
||||
|
||||
|
||||
crm_make_sale()
|
||||
|
||||
class sale_order_make_line(osv.osv_memory):
|
||||
|
||||
|
||||
def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,
|
||||
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
|
||||
lang=False, update_tax=True, date_order=False, packaging=False, fiscal_position=False, flag=False):
|
||||
if not partner_id:
|
||||
raise osv.except_osv(_('No Customer Defined !'), _('You have to select a customer in the sale form !\nPlease set one customer before choosing a product.'))
|
||||
warning = {}
|
||||
product_uom_obj = self.pool.get('product.uom')
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
product_obj = self.pool.get('product.product')
|
||||
if partner_id:
|
||||
lang = partner_obj.browse(cr, uid, partner_id).lang
|
||||
context = {'lang': lang, 'partner_id': partner_id}
|
||||
|
||||
if not product:
|
||||
return {'value': {'th_weight': 0, 'product_packaging': False,
|
||||
'product_uos_qty': qty}, 'domain': {'product_uom': [],
|
||||
'product_uos': []}}
|
||||
|
||||
if not date_order:
|
||||
date_order = time.strftime('%Y-%m-%d')
|
||||
|
||||
result = {}
|
||||
product_obj = product_obj.browse(cr, uid, product, context=context)
|
||||
if not packaging and product_obj.packaging:
|
||||
packaging = product_obj.packaging[0].id
|
||||
result['product_packaging'] = packaging
|
||||
|
||||
if packaging:
|
||||
default_uom = product_obj.uom_id and product_obj.uom_id.id
|
||||
pack = self.pool.get('product.packaging').browse(cr, uid, packaging, context=context)
|
||||
q = product_uom_obj._compute_qty(cr, uid, uom, pack.qty, default_uom)
|
||||
# qty = qty - qty % q + q
|
||||
if qty and (q and not (qty % q) == 0):
|
||||
ean = pack.ean
|
||||
qty_pack = pack.qty
|
||||
type_ul = pack.ul
|
||||
warn_msg = _("You selected a quantity of %d Units.\nBut it's not compatible with the selected packaging.\nHere is a proposition of quantities according to the packaging: ") % (qty)
|
||||
warn_msg = warn_msg + "\n\n" + _("EAN: ") + str(ean) + _(" Quantity: ") + str(qty_pack) + _(" Type of ul: ") + str(type_ul.name)
|
||||
warning = {
|
||||
'title': _('Picking Information !'),
|
||||
'message': warn_msg
|
||||
}
|
||||
result['product_uom_qty'] = qty
|
||||
|
||||
uom2 = False
|
||||
if uom:
|
||||
uom2 = product_uom_obj.browse(cr, uid, uom)
|
||||
if product_obj.uom_id.category_id.id != uom2.category_id.id:
|
||||
uom = False
|
||||
|
||||
if uos:
|
||||
if product_obj.uos_id:
|
||||
uos2 = product_uom_obj.browse(cr, uid, uos)
|
||||
if product_obj.uos_id.category_id.id != uos2.category_id.id:
|
||||
uos = False
|
||||
else:
|
||||
uos = False
|
||||
if product_obj.description_sale:
|
||||
result['notes'] = product_obj.description_sale
|
||||
fpos = fiscal_position and self.pool.get('account.fiscal.position').browse(cr, uid, fiscal_position) or False
|
||||
if update_tax: #The quantity only have changed
|
||||
result['delay'] = (product_obj.sale_delay or 0.0)
|
||||
partner = partner_obj.browse(cr, uid, partner_id)
|
||||
result['tax_id'] = self.pool.get('account.fiscal.position').map_tax(cr, uid, fpos, product_obj.taxes_id)
|
||||
result.update({'type': product_obj.procure_method})
|
||||
|
||||
if not flag:
|
||||
result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context)[0][1]
|
||||
domain = {}
|
||||
if (not uom) and (not uos):
|
||||
result['product_uom'] = product_obj.uom_id.id
|
||||
if product_obj.uos_id:
|
||||
result['product_uos'] = product_obj.uos_id.id
|
||||
result['product_uos_qty'] = qty * product_obj.uos_coeff
|
||||
uos_category_id = product_obj.uos_id.category_id.id
|
||||
else:
|
||||
result['product_uos'] = False
|
||||
result['product_uos_qty'] = qty
|
||||
uos_category_id = False
|
||||
domain = {'product_uom':
|
||||
[('category_id', '=', product_obj.uom_id.category_id.id)],
|
||||
'product_uos':
|
||||
[('category_id', '=', uos_category_id)]}
|
||||
|
||||
elif uos and not uom: # only happens if uom is False
|
||||
result['product_uom'] = product_obj.uom_id and product_obj.uom_id.id
|
||||
result['product_uom_qty'] = qty_uos / product_obj.uos_coeff
|
||||
elif uom: # whether uos is set or not
|
||||
default_uom = product_obj.uom_id and product_obj.uom_id.id
|
||||
q = product_uom_obj._compute_qty(cr, uid, uom, qty, default_uom)
|
||||
if product_obj.uos_id:
|
||||
result['product_uos'] = product_obj.uos_id.id
|
||||
result['product_uos_qty'] = qty * product_obj.uos_coeff
|
||||
else:
|
||||
result['product_uos'] = False
|
||||
result['product_uos_qty'] = qty
|
||||
|
||||
if not uom2:
|
||||
uom2 = product_obj.uom_id
|
||||
return {'value': result, 'domain': domain, 'warning': warning}
|
||||
|
||||
def product_uom_change(self, cursor, user, ids, pricelist, product, qty=0,
|
||||
uom=False, qty_uos=0, uos=False, name='', partner_id=False,
|
||||
lang=False, update_tax=True, date_order=False):
|
||||
res = self.product_id_change(cursor, user, ids, pricelist, product,
|
||||
qty=qty, uom=uom, qty_uos=qty_uos, uos=uos, name=name,
|
||||
partner_id=partner_id, lang=lang, update_tax=update_tax,
|
||||
date_order=date_order)
|
||||
if 'product_uom' in res['value']:
|
||||
del res['value']['product_uom']
|
||||
if not uom:
|
||||
res['value']['price_unit'] = 0.0
|
||||
return res
|
||||
|
||||
_name = 'sale.order.make.line'
|
||||
_description = 'Sale Order Line'
|
||||
_columns = {
|
||||
'order_line': fields.many2one('crm.make.sale', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
|
||||
'order_id': fields.many2one('sale.order', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=True, ),
|
||||
'name': fields.char('Description', size=256, required=True, select=True, readonly=True, ),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of sale order lines."),
|
||||
'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation the the shipping of the products to the customer", readonly=True, ),
|
||||
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
|
||||
'procurement_id': fields.many2one('procurement.order', 'Procurement'),
|
||||
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Sale Price'), readonly=True, ),
|
||||
'tax_id': fields.many2many('account.tax', 'sale_order_tax', 'order_line_id', 'tax_id', 'Taxes', readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'type': fields.selection([('make_to_stock', 'from stock'), ('make_to_order', 'on order')], 'Procurement Method', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'product_uom_qty': fields.float('Quantity (UoM)', digits=(16, 2), required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'product_uom': fields.many2one('product.uom', 'Unit of Measure ', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'product_uos_qty': fields.float('Quantity (UoS)', readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'product_uos': fields.many2one('product.uom', 'Product UoS'),
|
||||
'product_packaging': fields.many2one('product.packaging', 'Packaging'),
|
||||
'discount': fields.float('Discount (%)', digits=(16, 2), readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'notes': fields.text('Notes'),
|
||||
}
|
||||
_order = 'sequence, id'
|
||||
_defaults = {
|
||||
'discount': 0.0,
|
||||
'delay': 0.0,
|
||||
'product_uom_qty': 1,
|
||||
'product_uos_qty': 1,
|
||||
'type': 'make_to_stock',
|
||||
'product_packaging': False
|
||||
}
|
||||
|
||||
sale_order_make_line()
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -9,21 +9,66 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create a Sale Order" >
|
||||
<group width="660" height="300">
|
||||
<group colspan="4">
|
||||
<field name="partner_id" required="1"/>
|
||||
<field name="shop_id" required="1" widget="selection"/>
|
||||
<field name="analytic_account"/>
|
||||
<field name="picking_policy"/>
|
||||
<field name="close" required="1"/>
|
||||
</group>
|
||||
<separator string="Products" colspan="4"/>
|
||||
<field name="product_ids" colspan="4" nolabel="1"/>
|
||||
</group>
|
||||
<field colspan="4" mode="tree,form,graph" name="sale_order_line" nolabel="1" widget="one2many_list">
|
||||
<form string="Sale Order Lines">
|
||||
<notebook>
|
||||
<page string="Order Line">
|
||||
<field colspan="4"
|
||||
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
|
||||
name="product_id"
|
||||
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], True, parent.date_order, product_packaging, parent.fiscal_position, False)"
|
||||
/>
|
||||
<field
|
||||
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
|
||||
name="product_uom_qty"
|
||||
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position, True)"
|
||||
/>
|
||||
<field groups="product.group_uos" name="product_uos_qty"/>
|
||||
<field name="product_uom"
|
||||
on_change="product_uom_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order)"/>
|
||||
<field
|
||||
name="product_packaging"
|
||||
context="partner_id=parent.partner_id,quantity=product_uom_qty,pricelist=parent.pricelist_id,shop=parent.shop_id,uom=product_uom"
|
||||
on_change="product_id_change(parent.pricelist_id,product_id,product_uom_qty,product_uom,product_uos_qty,product_uos,name,parent.partner_id, 'lang' in context and context['lang'], False, parent.date_order, product_packaging, parent.fiscal_position, False)"
|
||||
domain="[('product_id','=',product_id)]"
|
||||
groups="base.group_extended"/>
|
||||
|
||||
<field colspan="4" name="name"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="discount"/>
|
||||
<field name="type" groups="base.group_extended"/>
|
||||
<field name="delay" groups="base.group_extended"/>
|
||||
<newline/>
|
||||
<separator colspan="5" string="Taxes"/>
|
||||
<field colspan="4" name="tax_id" nolabel="1" domain="[('parent_id','=',False),('type_tax_use','<>','purchase')]"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
<tree string="Sales order lines">
|
||||
<field colspan="4" name="name"/>
|
||||
<field name="product_uom_qty" string="Qty"/>
|
||||
<field name="product_uom" string="UoM"/>
|
||||
<field name="discount"/>
|
||||
<field name="price_unit"/>
|
||||
</tree>
|
||||
</field>
|
||||
<newline/>
|
||||
|
||||
|
||||
<separator colspan="4"/>
|
||||
<group col="4" colspan="4">
|
||||
<label string="" colspan="2"/>
|
||||
<button special="cancel" string="_Close" icon="gtk-cancel"/>
|
||||
<button name="makeOrder" string="_Ok" type="object" icon='gtk-ok'/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -248,7 +248,7 @@ class scrum_product_backlog(osv.osv):
|
||||
'note' : fields.text('Note'),
|
||||
'active' : fields.boolean('Active', help="If Active field is set to true, it will allow you to hide the product backlog without removing it."),
|
||||
'project_id': fields.many2one('project.project', 'Project', required=True, domain=[('scrum','=',1)], help="If you have [?] in the project name, it means there are no analytic account linked to this project."),
|
||||
'user_id': fields.many2one('res.users', 'Responsible'),
|
||||
'user_id': fields.many2one('res.users', 'Author'),
|
||||
'sprint_id': fields.many2one('scrum.sprint', 'Sprint'),
|
||||
'sequence' : fields.integer('Sequence', help="Gives the sequence order when displaying a list of product backlog."),
|
||||
'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'),
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
icon="terp-check"
|
||||
string="Current"
|
||||
name="current"
|
||||
domain="['|','&',('sprint_id.date_start','<=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','>=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open'])]"
|
||||
domain="['|','&',('sprint_id.date_start','<=',time.strftime('%%Y-%%m-%%d')), ('sprint_id.date_stop','>=',time.strftime('%%Y-%%m-%%d')), ('state','in',['draft','open','pending'])]"
|
||||
help="Current Backlogs"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]" help="Draft Backlogs"/>
|
||||
@@ -156,7 +156,8 @@
|
||||
<filter icon="terp-project"
|
||||
string="My Backlogs"
|
||||
name="my_user_id"
|
||||
domain="[('user_id','=',uid)]"/>
|
||||
domain="[('user_id','=',uid)]"
|
||||
help="My Backlogs"/>
|
||||
</field>
|
||||
</group>
|
||||
<newline/>
|
||||
@@ -178,7 +179,7 @@
|
||||
<field name="name">Product Backlogs</field>
|
||||
<field name="res_model">scrum.product.backlog</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="context">{"search_default_user_id":uid, 'search_default_current': 1}</field>
|
||||
<field name="context">{'search_default_current': 1}</field>
|
||||
<field name="search_view_id" ref="view_scrum_product_backlog_search"/>
|
||||
</record>
|
||||
<menuitem
|
||||
|
||||
@@ -96,9 +96,8 @@ class scrum_backlog_merge(osv.osv_memory):
|
||||
|
||||
#To assing a new product backlog to merged tasks
|
||||
task_obj.write(cr, uid, task_lines, {'product_backlog_id': id_b})
|
||||
backlog_obj.write(cr, uid, context['active_ids'], {'state':'done'}, context=context)
|
||||
backlog_obj.unlink(cr, uid, context['active_ids'], context=context)
|
||||
return {}
|
||||
|
||||
scrum_backlog_merge()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -7,21 +7,34 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Merge Backlogs">
|
||||
<label colspan="4" string="This wizard merge backlogs and create one new backlog with draft state (Old backlogs state changed to Done). And it also merge old tasks from backlogs" />
|
||||
<separator string="Are you sure you want to merge these Backlogs?" colspan="4"/>
|
||||
<label colspan="4" string="This wizard merge backlogs and create one new backlog with draft state (Old backlogs Will be deleted). And it also merge old tasks from backlogs" />
|
||||
<separator colspan="4"/>
|
||||
<button colspan="2" special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button colspan="2" default_focus="1" name="check_backlogs" string="Merge" type="object" icon="gtk-execute"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window name="Merge Backlogs"
|
||||
res_model="scrum.backlog.merge"
|
||||
src_model="scrum.product.backlog"
|
||||
view_mode="form"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_scrum_backlog_merge"/>
|
||||
<record id="action_scrum_backlog_merge" model="ir.actions.act_window">
|
||||
<field name="name">Merge Backlogs</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">scrum.backlog.merge</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="scrum_backlog_merge_view"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.values" id="scrum_backlog_merge_values">
|
||||
<field name="model_id" ref="model_scrum_product_backlog" />
|
||||
<field name="object" eval="1" />
|
||||
<field name="name">Merge Backlogs</field>
|
||||
<field name="key2">client_action_multi</field>
|
||||
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_scrum_backlog_merge'))" />
|
||||
<field name="key">action</field>
|
||||
<field name="model">scrum.product.backlog</field>
|
||||
</record>
|
||||
|
||||
<record id="scrum_merge_project_id_view" model="ir.ui.view">
|
||||
<field name="name">Merge Backlogs</field>
|
||||
@@ -29,11 +42,11 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Merge Backlogs">
|
||||
<separator string="Select the Project" colspan="4"/>
|
||||
<field name="project_id"/>
|
||||
<separator colspan="4"/>
|
||||
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button name="do_merge" string="Merge Backlogs" type="object" icon="gtk-execute"/>
|
||||
<separator string="Select the project for merged backlogs" colspan="4"/>
|
||||
<field name="project_id"/>
|
||||
<separator colspan="4"/>
|
||||
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button name="do_merge" string="Merge Backlogs" type="object" icon="gtk-execute"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -34,7 +34,7 @@ class survey_print(osv.osv_memory):
|
||||
('horizontal','Landscape(Horizontal)')], 'Orientation'),
|
||||
'paper_size' : fields.selection([('letter','Letter (8.5" x 11")'),\
|
||||
('legal','Legal (8.5" x 14")'),('a4','A4 (210mm x 297mm)')], 'Paper Size'),
|
||||
'page_number' : fields.boolean('Include Page Numvers'),
|
||||
'page_number' : fields.boolean('Include Page Number'),
|
||||
'without_pagebreak' : fields.boolean('Print Without Page Breaks'),
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class survey_print_answer(osv.osv_memory):
|
||||
'paper_size': fields.selection([('letter','Letter (8.5" x 11")'),\
|
||||
('legal','Legal (8.5" x 14")'),\
|
||||
('a4','A4 (210mm x 297mm)')], 'Paper Size'),
|
||||
'page_number': fields.boolean('Include Page Numvers'),
|
||||
'page_number': fields.boolean('Include Page Number'),
|
||||
'without_pagebreak': fields.boolean('Print Without Page Breaks')
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user