1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
21
from osv import fields,osv
22
from mx import DateTime
24
#TODO make this configurable parameters:
25
fixed_month_init_day = 1
26
fixed_default_anniversary_month = 12
28
class stock_location(osv.osv):
29
_inherit = "stock.location"
32
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
33
if view_type == 'form' and context.get('fleet_type', False) == 'sub_fleet':
34
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name','=','stock.location.fleet.form.sub_fleet_maintenance')])[0]
35
elif view_type == 'form' and context.get('fleet_type', False) == 'fleet':
36
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name','=','stock.location.fleet.form.fleet_maintenance')])[0]
37
elif view_type == 'tree' and context.get('fleet_type', False) == 'sub_fleet':
38
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name','=','sub_fleet.tree')])[0]
39
#elif view_type == 'tree' and context.get('fleet_type', False) == 'fleet':
41
return super(stock_location, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
44
def _is_expired(self, cr, uid, ids, field_name, arg, context={}):
47
date = DateTime.DateTime(now.year, now.month, now.day, 0, 0, 0.0)
48
for fleet in self.browse(cr, uid, ids, context):
50
res[fleet.id] = date > DateTime.strptime(fleet.expire_time, '%Y-%m-%d')
52
res[fleet.id] = True #by default no maintenance expire terms means no coverage
56
def _expire_time(self, cr, uid, ids, field_name, arg, context={}):
58
for fleet in self.browse(cr, uid, ids, context):
60
for invoice_line in fleet.account_invoice_lines:
61
if invoice_line.maintenance_end_date > max_time:
62
max_time = invoice_line.maintenance_end_date
63
res[fleet.id] = max_time
66
def _time_to_expire(self, cr, uid, ids, field_name, arg, context={}):
69
date = DateTime.DateTime(now.year, now.month, now.day)
70
for fleet in self.browse(cr, uid, ids, context):
71
res[fleet.id] = fleet.expire_time and int((DateTime.strptime(fleet.expire_time, '%Y-%m-%d') - date).days) or False
74
#retrieve anniversary time from parent eventually
75
def _anniversary_time(self, cr, uid, ids, field_name, arg, context={}):
77
for fleet in self.browse(cr, uid, ids, context):
78
res[fleet.id] = fleet.location_id and fleet.location_id.intrinsic_anniversary_time or fleet.intrinsic_anniversary_time
83
'fleet_type': fields.selection([('none','Not a Fleet'),('fleet','Fleet'),('sub_fleet','Sub Fleet')], 'Fleet type', required=False),
84
'partner_id': fields.many2one('res.partner', 'Customer', required = False, ondelete = 'cascade', select = True),
85
'parent_partner_id': fields.related('location_id', 'partner_id', type='many2one', relation='res.partner', string='Customer', store=True),
86
'sale_order_lines': fields.one2many('sale.order.line', 'fleet_id', 'Sale Order Lines'),
87
'fleet_sale_order_lines': fields.one2many('sale.order.line', 'parent_fleet_id', 'Sale Order Lines'),
88
'account_invoice_lines': fields.one2many('account.invoice.line', 'fleet_id', 'Invoice Lines'),
89
'fleet_account_invoice_lines': fields.one2many('account.invoice.line', 'parent_fleet_id', 'Invoice Lines'),
90
'crm_cases': fields.one2many('crm.case', 'fleet_id', 'Events'),
91
'fleet_crm_cases': fields.one2many('crm.case', 'parent_fleet_id', 'Events'),
92
'is_expired': fields.function(_is_expired, method=True, type='boolean', string="Expired ?"),
93
'time_to_expire': fields.function(_time_to_expire, method=True, type='integer', string="Days before expiry"),
94
'intrinsic_anniversary_time':fields.date('Intrinsic Time', required = False),
95
'anniversary_time':fields.function(_anniversary_time, method=True, type='date', string="Anniversary Time"), #TODO no year!
96
'expire_time':fields.function(_expire_time, method=True, type='date', string="Maintenance Expire Time"),
100
def intrinsic_anniversary_time_change(self, cr, uid, ids, anniversary_time=False):
103
anniversary_time = DateTime.strptime(anniversary_time, '%Y-%m-%d')
104
if anniversary_time.day != fixed_month_init_day:
105
anniversary_time = DateTime.DateTime(anniversary_time.year, anniversary_time.month, fixed_month_init_day)
106
result['value'] = {'intrinsic_anniversary_time': anniversary_time.strftime('%Y-%m-%d')}
107
result['warning'] = {'title':'Incorrect Anniversary Time', 'message':"- Anniversary date should should ideally start at day %s of the month; corrected to day %s\n" % (fixed_month_init_day, fixed_month_init_day)}
110
#FIXME: this call back is due to a current OpenERP limitation:
111
#currently (v5, March 2009), it's not possible to use the orm create method to create a hierarchy of objects all together within a single call.
112
#this is due to a bug/limitation of the Modified Pre-orderered Tree Traversal algorithm.
113
def sub_fleet_change(self, cr, uid, ids, fleet_id):
116
result['warning'] = {'title': 'Save PARENT FLEET first please!', 'message':'Due to a current OpenERP limitation, you should please close the SUBFLEET popup and save the form BEFORE adding any subfleet'}
117
result['value'] = {'child_ids':[]}
121
def _default_usage(self, cr, uid, context={}):
122
if context.get('fleet_type', 'none') != 'none':
126
def _default_anniversary_time(self, cr, uid, context={}):
127
date = DateTime.DateTime(DateTime.now().year, fixed_default_anniversary_month, fixed_month_init_day, 0, 0, 0.0)
128
return date.strftime('%Y-%m-%d')
130
def _default_fleet_type(self, cr, uid, context={}):
131
if context.get('fleet_type', 'none') == 'fleet':
133
elif context.get('fleet_type', 'none') == 'sub_fleet':
137
def _default_location_id(self, cr, uid, context={}):
138
if context.get('fleet_type', 'none') == 'fleet':
139
return 8 #FIXME, not very solid, rather use something like property_stock_customer
144
'usage': _default_usage,
145
'intrinsic_anniversary_time': _default_anniversary_time,
146
'fleet_type' : _default_fleet_type,
147
'location_id' : _default_location_id,
150
_constraints = [] #TODO
154
class stock_picking(osv.osv):
155
_inherit = "stock.picking"
157
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
158
if view_type == 'form' and context.get('view', False) == 'incident':
159
view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name','=','stock.picking.incident.form')])[0]
160
return super(stock_picking, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
163
#copy extra invoice line info when invoicing on delivery, if the "delivery" module is installed, it should be a dependence of this module for this to
165
def action_invoice_create(self, cr, uid, ids, journal_id=False,
166
group=False, type='out_invoice', context=None):
168
create_ids = super(stock_picking, self).action_invoice_create(cr, uid, ids, journal_id,
169
group, type, context)
171
for picking in self.browse(cr, uid, ids, context=context):
173
for order_line in picking.sale_id.order_line:
174
for invoice_line in order_line.invoice_lines:
175
if order_line.product_id and order_line.product_id.is_maintenance:
176
self.pool.get('account.invoice.line').write(cr, uid, invoice_line.id, {'maintenance_start_date':order_line.maintenance_start_date, \
177
'maintenance_end_date':order_line.maintenance_end_date, \
178
'maintenance_product_qty':order_line.maintenance_product_qty, \
179
'account_analytic_id':order_line.product_id.maintenance_analytic_id.id \
180
}) #TODO, we could use product categories to retrieve the maintenance_analytic_id
181
if order_line.fleet_id: #product sent to fleet but not maintenance -> we copy the information too
182
self.pool.get('account.invoice.line').write(cr, uid, invoice_line.id, {'fleet_id':order_line.fleet_id.id})
188
def _default_address_id(self, cr, uid, context={}):
189
address_return = False
190
if context.get('partner_id', False):
191
partner = self.pool.get('res.partner').browse(cr, uid, context.get('partner_id', False))
193
for address in partner.address:
194
if not address_return and address.type == "default":
195
address_return = address.id
196
if address.type == "delivery":
197
address_return = address.id
199
return address_return
203
'address_id': _default_address_id,
210
class stock_move(osv.osv):
211
_inherit = "stock.move"
213
def _default_product_id(self, cr, uid, context={}):
214
return context.get('product_id', False)
216
def _default_prodlot_id(self, cr, uid, context={}):
217
return context.get('prodlot_id', False)
219
def _default_location_id(self, cr, uid, context={}):
220
return context.get('location_id', False) or super(stock_move, self)._default_location_source(cr, uid, context)
222
def _default_location_dest_id(self, cr, uid, context={}):
223
return context.get('location_dest_id', False) or super(stock_move, self)._default_location_destination(cr, uid, context)
225
def _default_name(self, cr, uid, context={}):
230
'product_id': _default_product_id,
231
'prodlot_id': _default_prodlot_id,
232
'location_id': _default_location_id,
233
'location_dest_id': _default_location_dest_id,
234
'name': _default_name,