1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # POS Membership module for OpenERP, Manage membership payments from POS.
5 # Copyright (C) 2013 L'Heureux Cyclage (<http://www.heureux-cyclage.org>)
7 # This file is a part of POS Membership
9 # POS Membership is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
14 # ReMembership is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ##############################################################################
23 from openerp
import netsvc
24 from openerp
.osv
import fields
, osv
25 from openerp
.tools
.translate
import _
27 from datetime
import datetime
, date
28 from dateutil
.relativedelta
import relativedelta
32 ('none', 'Non Member'),
33 ('canceled', 'Cancelled Member'),
34 ('old', 'Old Member'),
35 ('waiting', 'Waiting Member'),
36 ('invoiced', 'Invoiced Member'),
37 ('free', 'Free Member'),
38 ('paid', 'Paid Member'),
41 class membership_line(osv
.osv
):
43 _inherit
= 'membership.membership_line'
45 def _get_partners(self
, cr
, uid
, ids
, context
=None):
46 list_membership_line
= []
47 member_line_obj
= self
.pool
.get('membership.membership_line')
48 for partner
in self
.pool
.get('res.partner').browse(cr
, uid
, ids
, context
=context
):
49 if partner
.member_lines
:
50 list_membership_line
+= member_line_obj
.search(cr
, uid
, [('id', 'in', [ l
.id for l
in partner
.member_lines
])], context
=context
)
51 return list_membership_line
53 #def _get_membership_lines_from_account_invoice(self, cr, uid, ids, context=None):
54 # list_membership_line = []
55 # member_line_obj = self.pool.get('membership.membership_line')
56 # for invoice in self.pool.get('account.invoice').browse(cr, uid, ids, context=context):
57 # if invoice.invoice_line:
58 # list_membership_line += member_line_obj.search(cr, uid, [('account_invoice_line', 'in', [ l.id for l in invoice.invoice_line])], context=context)
60 # { 'class': 'account.invoice'
61 # , 'ids': list_membership_line
63 # #res= list_membership_line
64 # print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_account_invoice]: res=%s" % str(res))
66 def _get_membership_lines_from_pos_order(self
, cr
, uid
, ids
, context
=None):
67 list_membership_line
= []
68 member_line_obj
= self
.pool
.get('membership.membership_line')
69 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
71 list_membership_line
+= member_line_obj
.search(cr
, uid
, [('pos_order_line', 'in', [ l
.id for l
in order
.lines
])], context
=context
)
73 { 'class': 'pos.order'
74 , 'ids': list_membership_line
76 #res= list_membership_line
77 print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_pos_order]: res=%s" % str(res
))
80 def _check_membership_date(self
, cr
, uid
, ids
, context
=None):
81 """Check if membership product is not in the past
82 @param self: The object pointer
83 @param cr: the current row, from the database cursor,
84 @param uid: the current user’s ID for security checks,
85 @param ids: List of Membership Line IDs
86 @param context: A standard dictionary for contextual values
90 SELECT MIN(ml.date_to - ai.date_invoice)
91 FROM membership_membership_line ml
92 JOIN account_invoice_line ail ON (
93 ml.account_invoice_line = ail.id
95 JOIN account_invoice ai ON (
96 ai.id = ail.invoice_id)
97 WHERE ml.id IN %s''', (tuple(ids
),))
100 if r
[0] and r
[0] < 0:
103 SELECT MIN(ml.date_to - ai.date_order)
104 FROM membership_membership_line ml
105 JOIN pos_order_line ail ON (
106 ml.pos_order_line = ail.id
108 JOIN pos_order ai ON (
109 ai.id = ail.order_id)
110 WHERE ml.id IN %s''', (tuple(ids
),))
113 if r
[0] and r
[0] < 0:
117 def _state(self
, cr
, uid
, data
, name
, args
, context
=None):
118 """Compute the state lines
119 @param self: The object pointer
120 @param cr: the current row, from the database cursor,
121 @param uid: the current user’s ID for security checks,
122 @param ids: List of Membership Line IDs
123 @param name: Field Name
124 @param context: A standard dictionary for contextual values
125 @param return: Dictionary of state Value
128 print("DEV: [pos_membership] [membership_line] [_state]: name=%s data=%s args=%s context=%s" % (str(name
), str(data
), str(args
), str(context
)))
129 if type(data
) == type(list()) or data
.get('class') == 'account.invoice':
130 inv_obj
= self
.pool
.get('account.invoice')
131 if type(data
) == type(list()):
134 ids
= data
.get('ids')
135 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
137 SELECT i.state, i.id FROM
141 SELECT l.invoice_id FROM
142 account_invoice_line l WHERE
144 SELECT ml.account_invoice_line FROM
145 membership_membership_line ml WHERE
150 fetched
= cr
.fetchone()
152 res
[line
.id] = 'canceled'
156 if (istate
== 'draft') |
(istate
== 'proforma'):
158 elif istate
== 'open':
160 elif istate
== 'paid':
162 inv
= inv_obj
.browse(cr
, uid
, fetched
[1], context
=context
)
163 for payment
in inv
.payment_ids
:
164 if payment
.invoice
and payment
.invoice
.type == 'out_refund':
166 elif istate
== 'cancel':
169 elif data
.get('class') == 'pos.order':
170 ord_obj
= self
.pool
.get('pos.order')
171 for line
in self
.browse(cr
, uid
, data
.get('ids'), context
=context
):
173 SELECT i.state, i.id FROM
177 SELECT l.order_id FROM
178 pos_order_line l WHERE
180 SELECT ml.pos_order_line FROM
181 membership_membership_line ml WHERE
186 fetched
= cr
.fetchone()
188 res
[line
.id] = 'canceled'
192 if (ostate
== 'draft'):
194 elif (ostate
== 'paid') |
(ostate
== 'done') |
(ostate
== 'invoiced'):
196 # XXX: regarder l'équivalent de out_refund pour un pos.order
197 print("DEV: [pos_membership] [membership_line] [_state]: paid: TODO")
198 #inv = ord_obj.browse(cr, uid, fetched[1], context=context)
199 #for payment in inv.payment_ids:
200 # if payment.invoice and payment.invoice.type == 'out_refund':
202 elif ostate
== 'cancel':
208 'pos_order_line': fields
.many2one('pos.order.line', 'POS Order line', readonly
=True),
209 'pos_order_id': fields
.related('pos_order_line', 'order_id', type='many2one', relation
='pos.order', string
='Order', readonly
=True),
210 'state': fields
.function(_state
,
211 string
='Membership Status', type='selection',
214 #'account.invoice': (_get_membership_lines_from_account_invoice, ['state'], 10),
215 'pos.order': (_get_membership_lines_from_pos_order
, ['state'], 10),
216 'res.partner': (_get_partners
, ['membership_state'], 12),
217 }, help="""It indicates the membership status.
218 -Non Member: A member who has not applied for any membership.
219 -Cancelled Member: A member who has cancelled his membership.
220 -Old Member: A member whose membership date has expired.
221 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
222 -Invoiced Member: A member whose invoice has been created.
223 -Paid Member: A member who has paid the membership amount."""),
224 'company_id': fields
.related('account_invoice_line', 'invoice_id', 'company_id', type="many2one", relation
="res.company", string
="Company", readonly
=True, store
=True)
225 # XXX: pos_order_line a aussi un company_id
230 class Partner(osv
.osv
):
232 _inherit
= 'res.partner'
234 def _get_partner_id(self
, cr
, uid
, ids
, context
=None):
235 member_line_obj
= self
.pool
.get('membership.membership_line')
236 res_obj
= self
.pool
.get('res.partner')
237 data_inv
= member_line_obj
.browse(cr
, uid
, ids
, context
=context
)
239 for data
in data_inv
:
240 list_partner
.append(data
.partner
.id)
243 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
247 def _get_invoice_partner(self
, cr
, uid
, ids
, context
=None):
248 inv_obj
= self
.pool
.get('account.invoice')
249 res_obj
= self
.pool
.get('res.partner')
250 data_inv
= inv_obj
.browse(cr
, uid
, ids
, context
=context
)
252 for data
in data_inv
:
253 list_partner
.append(data
.partner_id
.id)
256 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
260 def _get_order_partner(self
, cr
, uid
, ids
, context
=None):
261 ord_obj
= self
.pool
.get('pos.order')
262 res_obj
= self
.pool
.get('res.partner')
263 data_ord
= ord_obj
.browse(cr
, uid
, ids
, context
=context
)
265 for data
in data_ord
:
266 list_partner
.append(data
.partner_id
.id)
269 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
273 def _membership_state(self
, cr
, uid
, ids
, name
, args
, context
=None):
274 """This Function return Membership State For Given Partner.
275 @param self: The object pointer
276 @param cr: the current row, from the database cursor,
277 @param uid: the current user’s ID for security checks,
278 @param ids: List of Partner IDs
279 @param name: Field Name
280 @param context: A standard dictionary for contextual values
281 @param return: Dictionary of Membership state Value
286 today
= time
.strftime('%Y-%m-%d')
288 partner_data
= self
.browse(cr
, uid
, id, context
=context
)
289 if partner_data
.membership_cancel
and today
> partner_data
.membership_cancel
:
292 if partner_data
.membership_stop
and today
> partner_data
.membership_stop
:
296 if partner_data
.member_lines
:
297 for mline
in partner_data
.member_lines
:
298 if mline
.date_to
>= today
:
299 if mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
:
300 mstate
= mline
.account_invoice_line
.invoice_id
.state
303 inv
= mline
.account_invoice_line
.invoice_id
304 for payment
in inv
.payment_ids
:
305 if payment
.invoice
.type == 'out_refund':
308 elif mstate
== 'open' and s
!=0:
310 elif mstate
== 'cancel' and s
!=0 and s
!=1:
312 elif (mstate
== 'draft' or mstate
== 'proforma') and s
!=0 and s
!=1:
314 elif mline
.order_pos_line
and mline
.order_pos_line
.order_id
:
315 mstate
= mline
.pos_order_line
.order_id
.state
316 if (mstate
== 'paid') |
(mstate
== 'done') |
(mstate
== 'paid'):
318 # XXX: regarder l'équivalent de out_refund pour un pos.order
319 print("DEV: [pos_membership] [partner] [_membership_state]: paid: TODO")
320 #inv = mline.pos_order_line.order_id
321 #for payment in inv.payment_ids:
322 # if payment.invoice.type == 'out_refund':
325 elif mstate
== 'open' and s
!=0:
326 # XXX: 1 donne invoiced, c'est pitet pas bon
327 print("DEV: [pos_membership] [partner] [_membership_state]: invoiced: TODO")
329 elif mstate
== 'cancel' and s
!=0 and s
!=1:
331 elif mstate
== 'draft' and s
!=0 and s
!=1:
334 for mline
in partner_data
.member_lines
:
335 if mline
.date_from
< today
and \
336 mline
.date_to
< today
and \
337 mline
.date_from
<= mline
.date_to
and \
338 ( (mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
.state
) == 'paid' or \
339 ( mline
.pos_order_line
and \
340 ( mline
.pos_order_line
.order_id
.state
== 'paid' or \
341 mline
.pos_order_line
.order_id
.state
== 'done' or \
342 mline
.pos_order_line
.order_id
.state
== 'invoiced' ))):
358 if partner_data
.free_member
and s
!=0:
360 if partner_data
.associate_member
:
361 res_state
= self
._membership
_state
(cr
, uid
, [partner_data
.associate_member
.id], name
, args
, context
=context
)
362 res
[id] = res_state
[partner_data
.associate_member
.id]
365 def _membership_date(self
, cr
, uid
, ids
, name
, args
, context
=None):
366 """Return date of membership"""
369 member_line_obj
= self
.pool
.get('membership.membership_line')
370 for partner
in self
.browse(cr
, uid
, ids
, context
=context
):
371 if partner
.associate_member
:
372 partner_id
= partner
.associate_member
.id
374 partner_id
= partner
.id
376 'membership_start': False,
377 'membership_stop': False,
378 'membership_cancel': False
380 if name
== 'membership_start':
381 line_id
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
382 limit
=1, order
='date_from', context
=context
)
384 res
[partner
.id]['membership_start'] = member_line_obj
.read(cr
, uid
, line_id
[0],
385 ['date_from'], context
=context
)['date_from']
387 if name
== 'membership_stop':
388 line_id1
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
389 limit
=1, order
='date_to desc', context
=context
)
391 res
[partner
.id]['membership_stop'] = member_line_obj
.read(cr
, uid
, line_id1
[0],
392 ['date_to'], context
=context
)['date_to']
394 if name
== 'membership_cancel':
395 if partner
.membership_state
== 'canceled':
396 line_id2
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner
.id)], limit
=1, order
='date_cancel', context
=context
)
398 res
[partner
.id]['membership_cancel'] = member_line_obj
.read(cr
, uid
, line_id2
[0], ['date_cancel'], context
=context
)['date_cancel']
401 def _get_partners(self
, cr
, uid
, ids
, context
=None):
404 ids2
= self
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
408 def __get_membership_state(self
, *args
, **kwargs
):
409 return self
._membership
_state
(*args
, **kwargs
)
412 'associate_member': fields
.many2one('res.partner', 'Associate Member',help="A member with whom you want to associate your membership.It will consider the membership state of the associated member."),
413 'member_lines': fields
.one2many('membership.membership_line', 'partner', 'Membership'),
414 'free_member': fields
.boolean('Free Member', help = "Select if you want to give free membership."),
415 'membership_amount': fields
.float(
416 'Membership Amount', digits
=(16, 2),
417 help = 'The price negotiated by the partner'),
418 'membership_state': fields
.function(
419 __get_membership_state
,
420 string
= 'Current Membership Status', type = 'selection',
423 'account.invoice': (_get_invoice_partner
, ['state'], 10),
424 'pos.order': (_get_order_partner
, ['state'], 10),
425 'membership.membership_line': (_get_partner_id
, ['state'], 10),
426 'res.partner': (_get_partners
, ['free_member', 'membership_state', 'associate_member'], 10)
427 }, help="""It indicates the membership state.
428 -Non Member: A partner who has not applied for any membership.
429 -Cancelled Member: A member who has cancelled his membership.
430 -Old Member: A member whose membership date has expired.
431 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
432 -Invoiced Member: A member whose invoice has been created.
433 -Paying member: A member who has paid the membership fee."""),
434 'membership_start': fields
.function(
435 _membership_date
, multi
= 'membeship_start',
436 string
= 'Membership Start Date', type = 'date',
438 'account.invoice': (_get_invoice_partner
, ['state'], 10),
439 'pos.order': (_get_order_partner
, ['state'], 10),
440 'membership.membership_line': (_get_partner_id
, ['state'], 10, ),
441 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
442 }, help="Date from which membership becomes active."),
443 'membership_stop': fields
.function(
445 string
= 'Membership End Date', type='date', multi
='membership_stop',
447 'account.invoice': (_get_invoice_partner
, ['state'], 10),
448 'pos.order': (_get_order_partner
, ['state'], 10),
449 'membership.membership_line': (_get_partner_id
, ['state'], 10),
450 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
451 }, help="Date until which membership remains active."),
452 'membership_cancel': fields
.function(
454 string
= 'Cancel Membership Date', type='date', multi
='membership_cancel',
456 'account.invoice': (_get_invoice_partner
, ['state'], 11),
457 'pos.order': (_get_order_partner
, ['state'], 11),
458 'membership.membership_line': (_get_partner_id
, ['state'], 10),
459 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
460 }, help="Date on which membership has been cancelled"),
465 class pos_order(osv
.osv
):
466 _inherit
= 'pos.order'
468 def _check_membership_product(self
, cr
, uid
, ids
, context
=None):
469 #TODO : check condition and return boolean accordingly
470 if not context
is None:
472 order_line_obj
= self
.pool
.get('pos.order.line')
473 data_order_line
= order_line_obj
.browse(cr
, uid
, ids
, context
=context
)
474 for data
in data_order_line
:
475 print("DEV: [pos_membership] [_check_membership_product] [order_line]: data=%s product=%s" % (str(data
.id), str(data
.product_id
)))
479 (_check_membership_product
, 'Error: Invalid Message', ['field_name']),
482 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py
483 def action_invoice(self
, cr
, uid
, ids
, context
=None):
484 print ("DEV: [pos_membership] [pos_order] [action_invoice]")
485 wf_service
= netsvc
.LocalService("workflow")
486 inv_ref
= self
.pool
.get('account.invoice')
487 inv_line_ref
= self
.pool
.get('account.invoice.line')
488 product_obj
= self
.pool
.get('product.product')
491 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
493 inv_ids
.append(order
.invoice_id
.id)
496 if not order
.partner_id
:
497 raise osv
.except_osv(_('Error!'), _('Please provide a partner for the sale.'))
499 acc
= order
.partner_id
.property_account_receivable
.id
500 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py to fix account.invoice.line creation
503 'origin': order
.name
,
505 'journal_id': order
.sale_journal
.id or None,
506 'type': 'out_invoice',
507 'reference': order
.name
,
508 'partner_id': order
.partner_id
.id,
509 'comment': order
.note
or '',
510 'currency_id': order
.pricelist_id
.currency_id
.id, # considering partner's sale pricelist's currency
513 inv
.update(inv_ref
.onchange_partner_id(cr
, uid
, [], 'out_invoice', order
.partner_id
.id)['value'])
514 if not inv
.get('account_id', None):
515 inv
['account_id'] = acc
516 for line
in order
.lines
:
518 #'invoice_id': inv_id,
519 'product_id': line
.product_id
.id,
520 'quantity': line
.qty
,
522 inv_name
= product_obj
.name_get(cr
, uid
, [line
.product_id
.id], context
=context
)[0][1]
523 inv_line
.update(inv_line_ref
.product_id_change(cr
, uid
, [],
525 line
.product_id
.uom_id
.id,
526 line
.qty
, partner_id
= order
.partner_id
.id,
527 fposition_id
=order
.partner_id
.property_account_position
.id)['value'])
528 if line
.product_id
.description_sale
:
529 inv_line
['note'] = line
.product_id
.description_sale
530 inv_line
['price_unit'] = line
.price_unit
531 inv_line
['discount'] = line
.discount
532 inv_line
['name'] = inv_name
533 inv_line
['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line
)\
534 and [(6, 0, inv_line
['invoice_line_tax_id'])] or []
535 #inv_line_ref.create(cr, uid, inv_line, context=context)
536 inv
['invoice_line'].append((0, 0, inv_line
))
537 inv_id
= inv_ref
.create(cr
, uid
, inv
, context
=context
)
539 self
.write(cr
, uid
, [order
.id], {'invoice_id': inv_id
, 'state': 'invoiced'}, context
=context
)
540 inv_ref
.confirm_paid(cr
, uid
, [inv_id
], context
=context
)
541 inv_ids
.append(inv_id
)
542 inv_ref
.button_reset_taxes(cr
, uid
, [inv_id
], context
=context
)
543 wf_service
.trg_validate(uid
, 'pos.order', order
.id, 'invoice', cr
)
545 if not inv_ids
: return {}
547 mod_obj
= self
.pool
.get('ir.model.data')
548 res
= mod_obj
.get_object_reference(cr
, uid
, 'account', 'invoice_form')
549 res_id
= res
and res
[1] or False
551 'name': _('Customer Invoice'),
555 'res_model': 'account.invoice',
556 'context': "{'type':'out_invoice'}",
557 'type': 'ir.actions.act_window',
560 'res_id': inv_ids
and inv_ids
[0] or False,
565 class pos_order_line(osv
.osv
):
566 _inherit
= 'pos.order.line'
568 def write(self
, cr
, uid
, ids
, vals
, context
=None):
569 member_line_obj
= self
.pool
.get('membership.membership_line')
570 res
= super(pos_order_line
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
571 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
572 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
573 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
574 date_from
= line
.product_id
.membership_date_from
575 date_to
= line
.product_id
.membership_date_to
576 if line
.invoice_id
.date_invoice
> date_from
and line
.invoice_id
.date_invoice
< date_to
:
577 date_from
= line
.invoice_id
.date_invoice
579 if line
.product_id
.membership_date2date
:
580 date_from
= ('date_from' in context
581 and context
['date_from']
582 and datetime
.strptime(context
['date_from'], "%Y-%m-%d")
584 date_to
= date_from
+ relativedelta(months
= +12) # TODO: parameterize this delta?
585 date_from
= date_from
.strftime("%Y-%m-%d")
586 date_to
= date_to
.strftime("%Y-%m-%d")
587 print ("DEV: [pos_membership] [write] date_from: %s" % str(date_from
))
588 print ("DEV: [pos_membership] [write] date_to : %s" % str(date_to
))
589 member_line_obj
.create(cr
, uid
590 , { 'partner': line
.invoice_id
.partner_id
.id
591 , 'membership_id': line
.product_id
.id
592 , 'member_price': line
.price_unit
593 , 'date': time
.strftime('%Y-%m-%d')
594 , 'date_from': date_from
596 , 'pos_order_line': line
.id
599 if line
.product_id
.membership_grouped
:
600 if line
.order_id
.partner_id
.associate_members
:
601 associate_member_line_ids
= member_line_obj
.search(cr
, uid
602 , [ ('pos_order_line', '=', line
.id)
603 , ('partner', '!=', line
.order_id
.partner_id
.id)
606 for associate_member_line
in member_line_obj
.browse(cr
, uid
, associate_member_line_ids
, context
=context
):
607 print ("DEV: [pos_membership] [write] [associate] date_from: %s" % str(date_from
))
608 print ("DEV: [pos_membership] [write] [associate] date_to : %s" % str(date_to
))
609 member_line_obj
.write(cr
, uid
, associate_member_line
.id
610 , {'date_from': date_from
615 print("DEV: mettre une contrainte pour l'objet\
616 membership.membership_line interdisant les\
617 adhésions groupées reliées à des partenaires\
618 sans membres associés")
620 associate_member_line_ids
= member_line_obj
.search(cr
, uid
621 , [ ('pos_order_line', '=', line
.id)
622 , ('partner', '!=', line
.order_id
.partner_id
.id)
625 member_line_obj
.unlink(cr
, uid
, associate_member_line_ids
, context
=context
)
627 #Define member ident if it's necessary
628 partners
= [line
.order_id
.partner_id
]
629 if line
.order_id
.partner_id
.associate_members
:
630 partners
.extend(line
.order_id
.partner_id
.associate_members
)
632 if not i
.member_ident
:
633 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
634 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
635 if line
.product_id
and not line
.product_id
.membership
and ml_ids
:
636 # Product line has changed to a non membership product
637 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
640 def unlink(self
, cr
, uid
, ids
, context
=None):
641 """Remove Membership Line Record for Account Invoice Line
643 member_line_obj
= self
.pool
.get('membership.membership_line')
645 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', id)], context
=context
)
646 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
647 return super(pos_order_line
, self
).unlink(cr
, uid
, ids
, context
=context
)
649 def create(self
, cr
, uid
, vals
, context
=None):
650 member_line_obj
= self
.pool
.get('membership.membership_line')
651 res
= super(pos_order_line
, self
).create(cr
, uid
, vals
, context
=context
)
652 print ("DEV: [pos_membership] [pos_order_line] [create] : begin res=%s" % str(res
))
653 line
= self
.browse(cr
, uid
, res
, context
=context
)
655 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
656 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
657 date_from
= line
.product_id
.membership_date_from
658 date_to
= line
.product_id
.membership_date_to
659 if line
.order_id
.date_order
> date_from
and line
.order_id
.date_order
< date_to
:
660 date_from
= line
.order_id
.date_order
661 if line
.product_id
.membership_date2date
:
662 date_from
= ('date_from' in context
663 and context
.get('date_from')
664 and datetime
.strptime(context
.get('date_from'), "%Y-%m-%d")
666 date_to
= date_from
+ relativedelta(days
= +364) # TODO: parameterize this delta?
667 date_from
= date_from
.strftime("%Y-%m-%d")
668 date_to
= date_to
.strftime("%Y-%m-%d")
669 print ("DEV: [pos_membership] [pos_order_line] [create] date_from: %s" % str(date_from
))
670 print ("DEV: [pos_membership] [pos_order_line] [create] date_to : %s" % str(date_to
))
671 member_line_obj
.create(cr
, uid
, {
672 'partner': line
.order_id
.partner_id
and line
.order_id
.partner_id
.id or False,
673 'membership_id': line
.product_id
.id,
674 'member_price': line
.price_unit
,
675 'date': time
.strftime('%Y-%m-%d'),
676 'date_from': date_from
,
678 'pos_order_line': line
.id,
680 partners
= [line
.order_id
.partner_id
]
681 if line
.product_id
.membership_grouped
and line
.order_id
.partner_id
.associate_members
:
682 partners
.extend(line
.order_id
.partner_id
.associate_members
)
683 #Adding membership lines just for associate partners
684 for associate_member
in line
.order_id
.partner_id
.associate_members
:
685 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_from: %s" % str(date_from
))
686 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_to : %s" % str(date_to
))
687 member_line_obj
.create(cr
, uid
, {
688 'partner': associate_member
.id,
689 'membership_id': line
.product_id
.id,
690 'member_price': line
.price_unit
,
691 'date': time
.strftime('%Y-%m-%d'),
692 'date_from': date_from
,
694 'pos_order_line': line
.id,
696 elif line
.product_id
.membership_grouped
and not line
.order_id
.partner_id
.associate_members
:
697 raise osv
.except_osv(_('Error!!!'), _('You try to order grouped membership product to a partner who hasn\'t associated partners.'))
698 #Define member ident if it's necessary
701 print ("\033[7mXXX: [pos_membership] [pos_order_line] [create] : pos_order_line has no partner_id!\033[0m")
703 if not i
.member_ident
:
704 print ("DEV: [pos_membership] [pos_order_line] [create] [partners] : i=%s i.id=%s" % (str(i
), str(i
.id)))
705 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
706 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
707 print ("DEV: [pos_membership] [pos_order_line] [create] : return=%s" % str(res
))
712 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: