1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ##############################################################################
23 from osv import fields, osv
24 from tools import config
28 ('none', 'Non Member'),
29 ('canceled', 'Canceled Member'),
30 ('old', 'Old Member'),
31 ('waiting', 'Waiting Member'),
32 ('invoiced', 'Invoiced Member'),
33 ('free', 'Free Member'),
34 ('paid', 'Paid Member'),
47 #~ REQUETE = '''SELECT partner, state FROM (
48 #~ SELECT members.partner AS partner,
49 #~ CASE WHEN MAX(members.state) = 0 THEN 'none'
50 #~ ELSE CASE WHEN MAX(members.state) = 1 THEN 'canceled'
51 #~ ELSE CASE WHEN MAX(members.state) = 2 THEN 'old'
52 #~ ELSE CASE WHEN MAX(members.state) = 3 THEN 'waiting'
53 #~ ELSE CASE WHEN MAX(members.state) = 4 THEN 'invoiced'
54 #~ ELSE CASE WHEN MAX(members.state) = 6 THEN 'free'
55 #~ ELSE CASE WHEN MAX(members.state) = 7 THEN 'paid'
56 #~ END END END END END END END END
59 #~ CASE WHEN MAX(inv_digit.state) = 4 THEN 7
60 #~ ELSE CASE WHEN MAX(inv_digit.state) = 3 THEN 4
61 #~ ELSE CASE WHEN MAX(inv_digit.state) = 2 THEN 3
62 #~ ELSE CASE WHEN MAX(inv_digit.state) = 1 THEN 1
66 #~ SELECT p.id as partner,
67 #~ CASE WHEN ai.state = 'paid' THEN 4
68 #~ ELSE CASE WHEN ai.state = 'open' THEN 3
69 #~ ELSE CASE WHEN ai.state = 'proforma' THEN 2
70 #~ ELSE CASE WHEN ai.state = 'draft' THEN 2
71 #~ ELSE CASE WHEN ai.state = 'cancel' THEN 1
72 #~ END END END END END
75 #~ JOIN account_invoice ai ON (
76 #~ p.id = ai.partner_id
78 #~ JOIN account_invoice_line ail ON (
79 #~ ail.invoice_id = ai.id
81 #~ JOIN membership_membership_line ml ON (
82 #~ ml.account_invoice_line = ail.id
84 #~ WHERE ml.date_from <= '%s'
85 #~ AND ml.date_to >= '%s'
93 #~ SELECT p.id AS partner,
94 #~ CASE WHEN p.free_member THEN 6
95 #~ ELSE CASE WHEN p.associate_member IN (
96 #~ SELECT ai.partner_id FROM account_invoice ai JOIN
97 #~ account_invoice_line ail ON (ail.invoice_id = ai.id AND ai.state = 'paid')
98 #~ JOIN membership_membership_line ml ON (ml.account_invoice_line = ail.id)
99 #~ WHERE ml.date_from <= '%s'
100 #~ AND ml.date_to >= '%s'
105 #~ FROM res_partner p
106 #~ WHERE p.free_member
107 #~ OR p.associate_member > 0
109 #~ SELECT p.id as partner,
110 #~ MAX(CASE WHEN ai.state = 'paid' THEN 2
114 #~ FROM res_partner p
115 #~ JOIN account_invoice ai ON (
116 #~ p.id = ai.partner_id
118 #~ JOIN account_invoice_line ail ON (
119 #~ ail.invoice_id = ai.id
121 #~ JOIN membership_membership_line ml ON (
122 #~ ml.account_invoice_line = ail.id
124 #~ WHERE ml.date_from < '%s'
125 #~ AND ml.date_to < '%s'
126 #~ AND ml.date_from <= ml.date_to
131 #~ GROUP BY members.partner
137 class membership_line(osv.osv):
140 def _check_membership_date(self, cr, uid, ids, context=None):
141 '''Check if membership product is not in the past'''
144 SELECT MIN(ml.date_to - ai.date_invoice)
145 FROM membership_membership_line ml
146 JOIN account_invoice_line ail ON (
147 ml.account_invoice_line = ail.id
149 JOIN account_invoice ai ON (
150 ai.id = ail.invoice_id)
156 if r[0] and r[0] < 0:
160 def _state(self, cr, uid, ids, name, args, context=None):
161 '''Compute the state lines'''
163 for line in self.browse(cr, uid, ids):
165 SELECT i.state, i.id FROM
169 SELECT l.invoice_id FROM
170 account_invoice_line l WHERE
172 SELECT ml.account_invoice_line FROM
173 membership_membership_line ml WHERE
178 fetched = cr.fetchone()
180 res[line.id] = 'canceled'
184 if (istate == 'draft') | (istate == 'proforma'):
186 elif istate == 'open':
188 elif istate == 'paid':
190 inv = self.pool.get('account.invoice').browse(cr, uid, fetched[1])
191 for payment in inv.payment_ids:
192 if payment.invoice.type == 'out_refund':
194 elif istate == 'cancel':
200 _description = __doc__
201 _name = 'membership.membership_line'
203 'partner': fields.many2one('res.partner', 'Partner', ondelete='cascade', select=1),
204 'date_from': fields.date('From'),
205 'date_to': fields.date('To'),
206 'date_cancel' : fields.date('Cancel date'),
207 'account_invoice_line': fields.many2one('account.invoice.line', 'Account Invoice line'),
208 'state': fields.function(_state, method=True, string='State', type='selection', selection=STATE),
210 _rec_name = 'partner'
213 (_check_membership_date, 'Error, this membership product is out of date', [])
219 class Partner(osv.osv):
221 _inherit = 'res.partner'
223 def _get_partner_id(self, cr, uid, ids, context=None):
224 data_inv = self.pool.get('membership.membership_line').browse(cr, uid, ids, context)
226 for data in data_inv:
227 list_partner.append(data.partner.id)
230 ids2 = self.pool.get('res.partner').search(cr, uid, [('associate_member','in',ids2)], context=context)
234 def _get_invoice_partner(self, cr, uid, ids, context=None):
235 data_inv = self.pool.get('account.invoice').browse(cr, uid, ids, context)
237 for data in data_inv:
238 list_partner.append(data.partner_id.id)
241 ids2 = self.pool.get('res.partner').search(cr, uid, [('associate_member','in',ids2)], context=context)
245 def _membership_state(self, cr, uid, ids, name, args, context=None):
249 today = time.strftime('%Y-%m-%d')
251 partner_data = self.browse(cr,uid,id)
252 if partner_data.membership_cancel and today > partner_data.membership_cancel:
255 if partner_data.membership_stop and today > partner_data.membership_stop:
259 if partner_data.member_lines:
260 for mline in partner_data.member_lines:
261 if mline.date_to >= today:
262 if mline.account_invoice_line and mline.account_invoice_line.invoice_id:
263 mstate = mline.account_invoice_line.invoice_id.state
266 inv = mline.account_invoice_line.invoice_id
267 for payment in inv.payment_ids:
268 if payment.invoice.type == 'out_refund':
271 elif mstate == 'open' and s!=0:
273 elif mstate == 'cancel' and s!=0 and s!=1:
275 elif (mstate == 'draft' or mstate == 'proforma') and s!=0 and s!=1:
278 for mline in partner_data.member_lines:
279 if mline.date_from < today and mline.date_to < today and mline.date_from<=mline.date_to and (mline.account_invoice_line and mline.account_invoice_line.invoice_id.state) == 'paid':
295 if partner_data.free_member and s!=0:
297 if partner_data.associate_member:
298 res_state = self._membership_state(cr, uid, [partner_data.associate_member.id], name, args, context)
299 res[id] = res_state[partner_data.associate_member.id]
302 def _membership_start(self, cr, uid, ids, name, args, context=None):
303 '''Return the start date of membership'''
305 member_line_obj = self.pool.get('membership.membership_line')
306 for partner in self.browse(cr, uid, ids):
307 if partner.associate_member:
308 partner_id = partner.associate_member.id
310 partner_id = partner.id
311 line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
312 limit=1, order='date_from')
314 res[partner.id] = member_line_obj.read(cr, uid, line_id[0],
315 ['date_from'])['date_from']
317 res[partner.id] = False
320 def _membership_stop(self, cr, uid, ids, name, args, context=None):
321 '''Return the stop date of membership'''
323 member_line_obj = self.pool.get('membership.membership_line')
324 for partner in self.browse(cr, uid, ids):
325 cr.execute('select membership_state from res_partner where id=%s', (partner.id,))
326 data_state = cr.fetchall()
327 if partner.associate_member:
328 partner_id = partner.associate_member.id
330 partner_id = partner.id
331 line_id = member_line_obj.search(cr, uid, [('partner', '=', partner_id)],
332 limit=1, order='date_to desc')
334 res[partner.id] = member_line_obj.read(cr, uid, line_id[0],
335 ['date_to'])['date_to']
337 res[partner.id] = False
340 def _membership_cancel(self, cr, uid, ids, name, args, context=None):
341 '''Return the cancel date of membership'''
343 member_line_obj = self.pool.get('membership.membership_line')
344 for partner in self.browse(cr, uid, ids, context=context):
345 if partner.membership_state != 'canceled':
346 res[partner.id] = False
348 line_id = member_line_obj.search(cr, uid, [('partner', '=', partner.id)],
349 limit=1, order='date_cancel')
351 res[partner.id] = member_line_obj.read(cr, uid, line_id[0],
352 ['date_cancel'])['date_cancel']
354 res[partner.id] = False
357 def _get_partners(self, cr, uid, ids, context={}):
360 ids2 = self.search(cr, uid, [('associate_member','in',ids2)], context=context)
365 'associate_member': fields.many2one('res.partner', 'Associate member'),
366 'member_lines': fields.one2many('membership.membership_line', 'partner', 'Membership'),
367 'free_member': fields.boolean('Free member'),
368 'membership_amount': fields.float(
369 'Membership amount', digits=(16, 2),
370 help='The price negociated by the partner'),
371 'membership_state': fields.function(
372 _membership_state, method = True,
373 string = 'Current membership state', type = 'selection',
374 selection = STATE ,store = {
375 'account.invoice':(_get_invoice_partner,['state'], 10),
376 'membership.membership_line':(_get_partner_id,['state'], 10),
377 'res.partner':(_get_partners, ['free_member', 'membership_state', 'associate_member'], 10)
380 'membership_start': fields.function(
381 _membership_start, method=True,
382 string = 'Start membership date', type = 'date',
384 'account.invoice':(_get_invoice_partner,['state'], 10),
385 'membership.membership_line':(_get_partner_id,['state'], 10),
386 'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10)
389 'membership_stop': fields.function(
390 _membership_stop, method = True,
391 string = 'Stop membership date', type = 'date',
393 'account.invoice':(_get_invoice_partner,['state'], 10),
394 'membership.membership_line':(_get_partner_id,['state'], 10),
395 'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10)
399 'membership_cancel': fields.function(
400 _membership_cancel, method = True,
401 string = 'Cancel membership date', type='date',
403 'account.invoice':(_get_invoice_partner,['state'], 11),
404 'membership.membership_line':(_get_partner_id,['state'], 10),
405 'res.partner':(lambda self,cr,uid,ids,c={}:ids, ['free_member'], 10)
410 'free_member': lambda *a: False,
411 'membership_cancel' : lambda *d : False,
414 def _check_recursion(self, cr, uid, ids):
417 cr.execute('select distinct associate_member from res_partner where id in %s', (tuple(ids),))
418 ids = filter(None, map(lambda x:x[0], cr.fetchall()))
425 (_check_recursion, 'Error ! You can not create recursive associated members.', ['associate_member'])
430 class product_template(osv.osv):
431 _inherit = 'product.template'
433 'member_price':fields.float('Member Price', digits=(16, int(config['price_accuracy']))),
437 class Product(osv.osv):
439 def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False):
440 if ('product' in context) and (context['product']=='membership_product'):
441 model_data_ids_form = self.pool.get('ir.model.data').search(cr,user,[('model','=','ir.ui.view'),('name','in',['membership_products_form','membership_products_tree'])])
442 resource_id_form = self.pool.get('ir.model.data').read(cr,user,model_data_ids_form,fields=['res_id','name'])
444 for i in resource_id_form:
445 dict_model[i['name']]=i['res_id']
446 if view_type=='form':
447 view_id = dict_model['membership_products_form']
449 view_id = dict_model['membership_products_tree']
450 return super(Product,self).fields_view_get(cr, user, view_id, view_type, context, toolbar)
453 _inherit = 'product.product'
454 _description = 'product.product'
457 'membership': fields.boolean('Membership', help='Specify if this product is a membership product'),
458 'membership_date_from': fields.date('Date from'),
459 'membership_date_to': fields.date('Date to'),
460 # 'member_price':fields.float('Member Price'),
464 'membership': lambda *args: False
469 class Invoice(osv.osv):
472 _inherit = 'account.invoice'
474 def action_cancel(self, cr, uid, ids, context=None):
475 '''Create a 'date_cancel' on the membership_line object'''
478 member_line_obj = self.pool.get('membership.membership_line')
479 today = time.strftime('%Y-%m-%d')
480 for invoice in self.browse(cr, uid, ids):
481 mlines = member_line_obj.search(cr,uid,
482 [('account_invoice_line','in',
483 [ l.id for l in invoice.invoice_line])], context)
484 member_line_obj.write(cr,uid,mlines, {'date_cancel':today}, context)
485 return super(Invoice, self).action_cancel(cr, uid, ids, context)
489 class ReportPartnerMemberYear(osv.osv):
490 '''Membership by Years'''
492 _name = 'report.partner_member.year'
493 _description = __doc__
497 'year': fields.char('Year', size=4, readonly=True, select=1),
498 'canceled_number': fields.integer('Canceled', readonly=True),
499 'waiting_number': fields.integer('Waiting', readonly=True),
500 'invoiced_number': fields.integer('Invoiced', readonly=True),
501 'paid_number': fields.integer('Paid', readonly=True),
502 'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
503 'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
504 'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
505 'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
506 'currency': fields.many2one('res.currency', 'Currency', readonly=True,
511 '''Create the view'''
513 CREATE OR REPLACE VIEW report_partner_member_year AS (
516 COUNT(ncanceled) as canceled_number,
517 COUNT(npaid) as paid_number,
518 COUNT(ninvoiced) as invoiced_number,
519 COUNT(nwaiting) as waiting_number,
520 SUM(acanceled) as canceled_amount,
521 SUM(apaid) as paid_amount,
522 SUM(ainvoiced) as invoiced_amount,
523 SUM(awaiting) as waiting_amount,
527 CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
528 CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
529 CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
530 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
531 THEN ml.id END AS nwaiting,
532 CASE WHEN ai.state = 'cancel'
533 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
534 ELSE 0 END AS acanceled,
535 CASE WHEN ai.state = 'paid'
536 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
538 CASE WHEN ai.state = 'open'
539 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
540 ELSE 0 END AS ainvoiced,
541 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
542 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
543 ELSE 0 END AS awaiting,
544 TO_CHAR(ml.date_from, 'YYYY') AS year,
545 ai.currency_id AS currency,
547 FROM membership_membership_line ml
548 JOIN (account_invoice_line ail
549 LEFT JOIN account_invoice ai
550 ON (ail.invoice_id = ai.id))
551 ON (ml.account_invoice_line = ail.id)
553 ON (ml.partner = p.id)
554 GROUP BY TO_CHAR(ml.date_from, 'YYYY'), ai.state,
555 ai.currency_id, ml.id) AS foo
556 GROUP BY year, currency)
559 ReportPartnerMemberYear()
562 class ReportPartnerMemberYearNew(osv.osv):
563 '''New Membership by Years'''
565 _name = 'report.partner_member.year_new'
566 _description = __doc__
571 'year': fields.char('Year', size=4, readonly=True, select=1),
572 'canceled_number': fields.integer('Canceled', readonly=True),
573 'waiting_number': fields.integer('Waiting', readonly=True),
574 'invoiced_number': fields.integer('Invoiced', readonly=True),
575 'paid_number': fields.integer('Paid', readonly=True),
576 'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
577 'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
578 'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
579 'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
580 'currency': fields.many2one('res.currency', 'Currency', readonly=True,
585 '''Create the view'''
587 CREATE OR REPLACE VIEW report_partner_member_year AS (
590 COUNT(ncanceled) as canceled_number,
591 COUNT(npaid) as paid_number,
592 COUNT(ninvoiced) as invoiced_number,
593 COUNT(nwaiting) as waiting_number,
594 SUM(acanceled) as canceled_amount,
595 SUM(apaid) as paid_amount,
596 SUM(ainvoiced) as invoiced_amount,
597 SUM(awaiting) as waiting_amount,
601 CASE WHEN ai.state = 'cancel' THEN ml.id END AS ncanceled,
602 CASE WHEN ai.state = 'paid' THEN ml.id END AS npaid,
603 CASE WHEN ai.state = 'open' THEN ml.id END AS ninvoiced,
604 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
605 THEN ml.id END AS nwaiting,
606 CASE WHEN ai.state = 'cancel'
607 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
608 ELSE 0 END AS acanceled,
609 CASE WHEN ai.state = 'paid'
610 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
612 CASE WHEN ai.state = 'open'
613 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
614 ELSE 0 END AS ainvoiced,
615 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
616 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
617 ELSE 0 END AS awaiting,
618 TO_CHAR(ml.date_from, 'YYYY') AS year,
619 ai.currency_id AS currency,
621 FROM membership_membership_line ml
622 JOIN (account_invoice_line ail
623 LEFT JOIN account_invoice ai
624 ON (ail.invoice_id = ai.id))
625 ON (ml.account_invoice_line = ail.id)
627 ON (ml.partner = p.id)
628 GROUP BY TO_CHAR(ml.date_from, 'YYYY'), ai.state,
629 ai.currency_id, ml.id) AS foo
630 GROUP BY year, currency)
633 ReportPartnerMemberYear()
636 class ReportPartnerMemberYearNew(osv.osv):
637 '''New Membership by Years'''
639 _name = 'report.partner_member.year_new'
640 _description = __doc__
644 'year': fields.char('Year', size=4, readonly=True, select=1),
645 'canceled_number': fields.integer('Canceled', readonly=True),
646 'waiting_number': fields.integer('Waiting', readonly=True),
647 'invoiced_number': fields.integer('Invoiced', readonly=True),
648 'paid_number': fields.integer('Paid', readonly=True),
649 'canceled_amount': fields.float('Canceled', digits=(16, 2), readonly=True),
650 'waiting_amount': fields.float('Waiting', digits=(16, 2), readonly=True),
651 'invoiced_amount': fields.float('Invoiced', digits=(16, 2), readonly=True),
652 'paid_amount': fields.float('Paid', digits=(16, 2), readonly=True),
653 'currency': fields.many2one('res.currency', 'Currency', readonly=True,
657 def init(self, cursor):
658 '''Create the view'''
660 CREATE OR REPLACE VIEW report_partner_member_year_new AS (
663 COUNT(ncanceled) AS canceled_number,
664 COUNT(npaid) AS paid_number,
665 COUNT(ninvoiced) AS invoiced_number,
666 COUNT(nwaiting) AS waiting_number,
667 SUM(acanceled) AS canceled_amount,
668 SUM(apaid) AS paid_amount,
669 SUM(ainvoiced) AS invoiced_amount,
670 SUM(awaiting) AS waiting_amount,
674 CASE WHEN ai.state = 'cancel' THEN ml2.id END AS ncanceled,
675 CASE WHEN ai.state = 'paid' THEN ml2.id END AS npaid,
676 CASE WHEN ai.state = 'open' THEN ml2.id END AS ninvoiced,
677 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
678 THEN ml2.id END AS nwaiting,
679 CASE WHEN ai.state = 'cancel'
680 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
681 ELSE 0 END AS acanceled,
682 CASE WHEN ai.state = 'paid'
683 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
685 CASE WHEN ai.state = 'open'
686 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
687 ELSE 0 END AS ainvoiced,
688 CASE WHEN (ai.state = 'draft' OR ai.state = 'proforma')
689 THEN SUM(ail.price_unit * ail.quantity * (1 - ail.discount / 100))
690 ELSE 0 END AS awaiting,
691 TO_CHAR(ml2.date_from, 'YYYY') AS year,
692 ai.currency_id AS currency,
696 MIN(date_from) AS date_from
697 FROM membership_membership_line
700 JOIN membership_membership_line ml2
701 JOIN (account_invoice_line ail
702 LEFT JOIN account_invoice ai
703 ON (ail.invoice_id = ai.id))
704 ON (ml2.account_invoice_line = ail.id)
705 ON (ml1.id = ml2.partner AND ml1.date_from = ml2.date_from)
707 ON (ml2.partner = p.id)
708 GROUP BY TO_CHAR(ml2.date_from, 'YYYY'), ai.state,
709 ai.currency_id, ml2.id) AS foo
710 GROUP BY year, currency
714 ReportPartnerMemberYearNew()
716 class account_invoice_line(osv.osv):
717 _inherit='account.invoice.line'
718 def write(self, cr, uid, ids, vals, context=None):
721 res = super(account_invoice_line, self).write(cr, uid, ids, vals, context=context)
722 member_line_obj = self.pool.get('membership.membership_line')
723 for line in self.browse(cr, uid, ids):
724 if line.invoice_id.type == 'out_invoice':
725 ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
726 if line.product_id and line.product_id.membership and not ml_ids:
727 # Product line has changed to a membership product
728 date_from = line.product_id.membership_date_from
729 date_to = line.product_id.membership_date_to
730 if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
731 date_from = line.invoice_id.date_invoice
732 line_id = member_line_obj.create(cr, uid, {
733 'partner': line.invoice_id.partner_id.id,
734 'date_from': date_from,
736 'account_invoice_line': line.id,
738 if line.product_id and not line.product_id.membership and ml_ids:
739 # Product line has changed to a non membership product
740 member_line_obj.unlink(cr, uid, ml_ids, context=context)
743 def unlink(self, cr, uid, ids, context=None):
746 member_line_obj = self.pool.get('membership.membership_line')
748 ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',id)])
749 member_line_obj.unlink(cr, uid, ml_ids, context=context)
750 return super(account_invoice_line, self).unlink(cr, uid, ids, context=context)
752 def create(self, cr, uid, vals, context={}):
753 result = super(account_invoice_line, self).create(cr, uid, vals, context)
754 line = self.browse(cr, uid, result)
755 if line.invoice_id.type == 'out_invoice':
756 member_line_obj = self.pool.get('membership.membership_line')
757 ml_ids = member_line_obj.search(cr, uid, [('account_invoice_line','=',line.id)])
758 if line.product_id and line.product_id.membership and not ml_ids:
759 # Product line is a membership product
760 date_from = line.product_id.membership_date_from
761 date_to = line.product_id.membership_date_to
762 if line.invoice_id.date_invoice > date_from and line.invoice_id.date_invoice < date_to:
763 date_from = line.invoice_id.date_invoice
764 line_id = member_line_obj.create(cr, uid, {
765 'partner': line.invoice_id.partner_id and line.invoice_id.partner_id.id or False,
766 'date_from': date_from,
768 'account_invoice_line': line.id,
772 account_invoice_line()
773 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: