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 print("DEV: [pos_membership] [membership_line] [_get_partners]: ids=%s res=%s" % (str(ids
), str(list_membership_line
)))
52 return list_membership_line
54 #def _get_membership_lines_from_account_invoice(self, cr, uid, ids, context=None):
55 # list_membership_line = []
56 # member_line_obj = self.pool.get('membership.membership_line')
57 # for invoice in self.pool.get('account.invoice').browse(cr, uid, ids, context=context):
58 # if invoice.invoice_line:
59 # list_membership_line += member_line_obj.search(cr, uid, [('account_invoice_line', 'in', [ l.id for l in invoice.invoice_line])], context=context)
61 # { 'class': 'account.invoice'
62 # , 'ids': list_membership_line
64 # #res= list_membership_line
65 # print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_account_invoice]: res=%s" % str(res))
67 def _get_membership_lines_from_pos_order(self
, cr
, uid
, ids
, context
=None):
68 list_membership_line
= []
69 member_line_obj
= self
.pool
.get('membership.membership_line')
70 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
72 list_membership_line
+= member_line_obj
.search(cr
, uid
, [('pos_order_line', 'in', [ l
.id for l
in order
.lines
])], context
=context
)
74 # { 'class': 'pos.order'
75 # , 'ids': list_membership_line
77 res
= list_membership_line
78 print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_pos_order]: res=%s" % str(res
))
81 def _check_membership_date(self
, cr
, uid
, ids
, context
=None):
82 """Check if membership product is not in the past
83 @param self: The object pointer
84 @param cr: the current row, from the database cursor,
85 @param uid: the current user’s ID for security checks,
86 @param ids: List of Membership Line IDs
87 @param context: A standard dictionary for contextual values
91 SELECT MIN(ml.date_to - ai.date_invoice)
92 FROM membership_membership_line ml
93 JOIN account_invoice_line ail ON (
94 ml.account_invoice_line = ail.id
96 JOIN account_invoice ai ON (
97 ai.id = ail.invoice_id)
98 WHERE ml.id IN %s''', (tuple(ids
),))
101 if r
[0] and r
[0] < 0:
104 SELECT MIN(ml.date_to - ai.date_order)
105 FROM membership_membership_line ml
106 JOIN pos_order_line ail ON (
107 ml.pos_order_line = ail.id
109 JOIN pos_order ai ON (
110 ai.id = ail.order_id)
111 WHERE ml.id IN %s''', (tuple(ids
),))
114 if r
[0] and r
[0] < 0:
118 def _state(self
, cr
, uid
, ids
, name
, args
, context
=None):
119 """Compute the state lines
120 @param self: The object pointer
121 @param cr: the current row, from the database cursor,
122 @param uid: the current user’s ID for security checks,
123 @param ids: List of Membership Line IDs
124 @param name: Field Name
125 @param context: A standard dictionary for contextual values
126 @param return: Dictionary of state Value
129 print("DEV: [pos_membership] [membership_line] [_state]: name=%s ids=%s args=%s context=%s" % (str(name
), str(ids
), str(args
), str(context
)))
130 inv_obj
= self
.pool
.get('account.invoice')
131 ord_obj
= self
.pool
.get('pos.order')
132 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
134 SELECT i.state, i.id FROM
138 SELECT l.invoice_id FROM
139 account_invoice_line l WHERE
141 SELECT ml.account_invoice_line FROM
142 membership_membership_line ml WHERE
147 fetched
= cr
.fetchone()
151 if (istate
== 'draft') |
(istate
== 'proforma'):
153 elif istate
== 'open':
155 elif istate
== 'paid':
157 inv
= inv_obj
.browse(cr
, uid
, fetched
[1], context
=context
)
158 for payment
in inv
.payment_ids
:
159 if payment
.invoice
and payment
.invoice
.type == 'out_refund':
161 elif istate
== 'cancel':
166 SELECT i.state, i.id, i.partner_id FROM
170 SELECT l.order_id FROM
171 pos_order_line l WHERE
173 SELECT ml.pos_order_line FROM
174 membership_membership_line ml WHERE
179 fetched
= cr
.fetchone()
181 res
[line
.id] = 'canceled'
183 partner_id
= fetched
[2]
184 self
.write(cr
, uid
, line
.id, {'partner': partner_id
})
185 # NOTE: force une mise à jour du partner,
186 # car il n'y en a pas lors de la création du pos.order
187 # dans le PoS (pour le moment)
190 if (ostate
== 'paid') |
(ostate
== 'draft'):
192 elif (ostate
== 'done') |
(ostate
== 'invoiced'):
194 # XXX: regarder l'équivalent de out_refund pour un pos.order
195 print("DEV: [pos_membership] [membership_line] [_state]: paid: TODO")
196 #inv = ord_obj.browse(cr, uid, fetched[1], context=context)
197 #for payment in inv.payment_ids:
198 # if payment.invoice and payment.invoice.type == 'out_refund':
200 elif ostate
== 'cancel':
203 print("DEV: [pos_membership] [membership_line] [_state]: return=%s" % (str(res
)))
206 def write(self
, cr
, uid
, ids
, vals
, context
=None):
207 print("DEV: [pos_membership] [membership_line] [write]: ids=%s vals=%s" % (str(ids
), str(vals
)))
208 member_line_obj
= self
.pool
.get('membership.membership_line')
209 res
= super(membership_line
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
210 print("DEV: [pos_membership] [membership_line] [write]: res=%s" % str(res
))
213 def create(self
, cr
, uid
, vals
, context
=None):
214 print("DEV: [pos_membership] [membership_line] [create]: vals=%s" % (str(vals
)))
215 member_line_obj
= self
.pool
.get('membership.membership_line')
216 res
= super(membership_line
, self
).create(cr
, uid
, vals
, context
=context
)
217 print("DEV: [pos_membership] [membership_line] [create]: res=%s" % (str(res
)))
221 'pos_order_line': fields
.many2one('pos.order.line', 'POS Order line', readonly
=True),
222 'pos_order_id': fields
.related('pos_order_line', 'order_id', type='many2one', relation
='pos.order', string
='Order', readonly
=True),
223 'state': fields
.function(_state
,
224 string
='Membership Status', type='selection',
227 #'account.invoice': (_get_membership_lines_from_account_invoice, ['state'], 10),
228 # NOTE: déjà géré par membership.membership_line._get_membership_lines
229 'pos.order': (_get_membership_lines_from_pos_order
, ['state', 'partner_id'], 10),
230 'res.partner': (_get_partners
, ['membership_state'], 12),
231 }, help="""It indicates the membership status.
232 -Non Member: A member who has not applied for any membership.
233 -Cancelled Member: A member who has cancelled his membership.
234 -Old Member: A member whose membership date has expired.
235 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
236 -Invoiced Member: A member whose invoice has been created.
237 -Paid Member: A member who has paid the membership amount."""),
238 'company_id': fields
.related('account_invoice_line', 'invoice_id', 'company_id', type="many2one", relation
="res.company", string
="Company", readonly
=True, store
=True)
239 # XXX: pos_order_line a aussi un company_id
244 class Partner(osv
.osv
):
246 _inherit
= 'res.partner'
248 def _get_partner_id(self
, cr
, uid
, ids
, context
=None):
249 member_line_obj
= self
.pool
.get('membership.membership_line')
250 res_obj
= self
.pool
.get('res.partner')
251 data_inv
= member_line_obj
.browse(cr
, uid
, ids
, context
=context
)
253 for data
in data_inv
:
254 list_partner
.append(data
.partner
.id)
257 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
261 def _get_invoice_partner(self
, cr
, uid
, ids
, context
=None):
262 inv_obj
= self
.pool
.get('account.invoice')
263 res_obj
= self
.pool
.get('res.partner')
264 data_inv
= inv_obj
.browse(cr
, uid
, ids
, context
=context
)
266 for data
in data_inv
:
267 list_partner
.append(data
.partner_id
.id)
270 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
274 def _get_order_partner(self
, cr
, uid
, ids
, context
=None):
275 ord_obj
= self
.pool
.get('pos.order')
276 res_obj
= self
.pool
.get('res.partner')
277 data_ord
= ord_obj
.browse(cr
, uid
, ids
, context
=context
)
279 for data
in data_ord
:
280 list_partner
.append(data
.partner_id
.id)
283 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
287 def _membership_state(self
, cr
, uid
, ids
, name
, args
, context
=None):
288 """This Function return Membership State For Given Partner.
289 @param self: The object pointer
290 @param cr: the current row, from the database cursor,
291 @param uid: the current user’s ID for security checks,
292 @param ids: List of Partner IDs
293 @param name: Field Name
294 @param context: A standard dictionary for contextual values
295 @param return: Dictionary of Membership state Value
298 print("DEV: [pos_membership] [Partner] [_membership_state]: name=%s ids=%s args=%s context=%s" % (str(name
), str(ids
), str(args
), str(context
)))
301 today
= time
.strftime('%Y-%m-%d')
303 partner_data
= self
.browse(cr
, uid
, id, context
=context
)
304 if partner_data
.membership_cancel
and today
> partner_data
.membership_cancel
:
307 if partner_data
.membership_stop
and today
> partner_data
.membership_stop
:
311 if partner_data
.member_lines
:
312 print("DEV: [pos_membership] [Partner] [_membership_state] [partner_data] [member_lines]" % ())
313 for mline
in partner_data
.member_lines
:
314 print("DEV: [pos_membership] [Partner] [_membership_state] [mline]: id=%s" % str(mline
.id))
315 if mline
.date_to
>= today
:
316 if mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
:
317 istate
= mline
.account_invoice_line
.invoice_id
.state
318 print("DEV: [pos_membership] [Partner] [_membership_state] [account_invoice_line]: id=%s istate=%s" % (str(mline
.account_invoice_line
.invoice_id
.id), str(istate
)))
321 inv
= mline
.account_invoice_line
.invoice_id
322 for payment
in inv
.payment_ids
:
323 if payment
.invoice
.type == 'out_refund':
326 elif istate
== 'open' and s
!=0:
328 elif istate
== 'cancel' and s
!=0 and s
!=1:
330 elif (istate
== 'draft' or istate
== 'proforma') and s
!=0 and s
!=1:
332 elif mline
.pos_order_line
and mline
.pos_order_line
.order_id
:
333 ostate
= mline
.pos_order_line
.order_id
.state
334 print("DEV: [pos_membership] [Partner] [_membership_state] [pos_order_line]: id=%s ostate=%s" % (str(mline
.pos_order_line
.order_id
.id), str(ostate
)))
335 if ostate
== 'paid' and s
!=0 and s
!=1:
337 if ostate
== 'invoiced':
341 # XXX: regarder l'équivalent de out_refund pour un pos.order
342 print("DEV: [pos_membership] [partner] [_membership_state]: paid: TODO")
343 #inv = mline.pos_order_line.order_id
344 #for payment in inv.payment_ids:
345 # if payment.invoice.type == 'out_refund':
348 elif ostate
== 'open' and s
!=0:
349 # XXX: 1 donne invoiced, c'est pitet pas bon
350 print("DEV: [pos_membership] [partner] [_membership_state]: invoiced: TODO")
352 elif ostate
== 'cancel' and s
!=0 and s
!=1:
354 elif ostate
== 'draft' and s
!=0 and s
!=1:
357 for mline
in partner_data
.member_lines
:
358 if mline
.date_from
< today
and \
359 mline
.date_to
< today
and \
360 mline
.date_from
<= mline
.date_to
and \
361 ( (mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
.state
) == 'paid' or \
362 ( mline
.pos_order_line
and \
363 ( mline
.pos_order_line
.order_id
.state
== 'paid' or \
364 mline
.pos_order_line
.order_id
.state
== 'done' or \
365 mline
.pos_order_line
.order_id
.state
== 'invoiced' ))):
381 if partner_data
.free_member
and s
!=0:
383 if partner_data
.associate_member
:
384 res_state
= self
._membership
_state
(cr
, uid
, [partner_data
.associate_member
.id], name
, args
, context
=context
)
385 res
[id] = res_state
[partner_data
.associate_member
.id]
386 print("DEV: [pos_membership] [Partner] [_membership_state]: res=%s" % (str(res
)))
389 def _membership_date(self
, cr
, uid
, ids
, name
, args
, context
=None):
390 """Return date of membership"""
393 member_line_obj
= self
.pool
.get('membership.membership_line')
394 for partner
in self
.browse(cr
, uid
, ids
, context
=context
):
395 if partner
.associate_member
:
396 partner_id
= partner
.associate_member
.id
398 partner_id
= partner
.id
400 'membership_start': False,
401 'membership_stop': False,
402 'membership_cancel': False
404 if name
== 'membership_start':
405 line_id
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
406 limit
=1, order
='date_from', context
=context
)
408 res
[partner
.id]['membership_start'] = member_line_obj
.read(cr
, uid
, line_id
[0],
409 ['date_from'], context
=context
)['date_from']
411 if name
== 'membership_stop':
412 line_id1
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
413 limit
=1, order
='date_to desc', context
=context
)
415 res
[partner
.id]['membership_stop'] = member_line_obj
.read(cr
, uid
, line_id1
[0],
416 ['date_to'], context
=context
)['date_to']
418 if name
== 'membership_cancel':
419 if partner
.membership_state
== 'canceled':
420 line_id2
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner
.id)], limit
=1, order
='date_cancel', context
=context
)
422 res
[partner
.id]['membership_cancel'] = member_line_obj
.read(cr
, uid
, line_id2
[0], ['date_cancel'], context
=context
)['date_cancel']
425 def _get_partners(self
, cr
, uid
, ids
, context
=None):
428 ids2
= self
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
432 def __get_membership_state(self
, *args
, **kwargs
):
433 return self
._membership
_state
(*args
, **kwargs
)
436 'membership_state': fields
.function(
437 __get_membership_state
,
438 string
= 'Current Membership Status', type = 'selection',
441 # NOTE: il est important que la priorité soit plus grande
442 # que les membership_{start,stop,cancel}
443 # car _membership_state s'en sert et doit donc les trouver à jour.
444 'account.invoice': (_get_invoice_partner
, ['state'], 20),
445 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 20),
446 'membership.membership_line': (_get_partner_id
, ['state'], 20),
447 'res.partner': (_get_partners
, ['free_member', 'membership_state', 'associate_member'], 20)
448 }, help="""It indicates the membership state.
449 -Non Member: A partner who has not applied for any membership.
450 -Cancelled Member: A member who has cancelled his membership.
451 -Old Member: A member whose membership date has expired.
452 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
453 -Invoiced Member: A member whose invoice has been created.
454 -Paying member: A member who has paid the membership fee."""),
455 'membership_start': fields
.function(
456 _membership_date
, multi
= 'membeship_start',
457 string
= 'Membership Start Date', type = 'date',
459 'account.invoice': (_get_invoice_partner
, ['state'], 10),
460 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 10),
461 'membership.membership_line': (_get_partner_id
, ['state'], 10),
462 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
463 }, help="Date from which membership becomes active."),
464 'membership_stop': fields
.function(
466 string
= 'Membership End Date', type='date', multi
='membership_stop',
468 'account.invoice': (_get_invoice_partner
, ['state'], 10),
469 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 10),
470 'membership.membership_line': (_get_partner_id
, ['state'], 10),
471 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
472 }, help="Date until which membership remains active."),
473 'membership_cancel': fields
.function(
475 string
= 'Cancel Membership Date', type='date', multi
='membership_cancel',
477 'account.invoice': (_get_invoice_partner
, ['state'], 11),
478 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 11),
479 'membership.membership_line': (_get_partner_id
, ['state'], 10),
480 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
481 }, help="Date on which membership has been cancelled"),
486 class pos_order(osv
.osv
):
487 _inherit
= 'pos.order'
489 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py
490 def action_invoice(self
, cr
, uid
, ids
, context
=None):
491 print ("DEV: [pos_membership] [pos_order] [action_invoice]")
492 wf_service
= netsvc
.LocalService("workflow")
493 inv_ref
= self
.pool
.get('account.invoice')
494 inv_line_ref
= self
.pool
.get('account.invoice.line')
495 product_obj
= self
.pool
.get('product.product')
498 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
500 inv_ids
.append(order
.invoice_id
.id)
503 if not order
.partner_id
:
504 raise osv
.except_osv(_('Error!'), _('Please provide a partner for the sale.'))
506 acc
= order
.partner_id
.property_account_receivable
.id
507 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py to fix account.invoice.line creation
510 'origin': order
.name
,
512 'journal_id': order
.sale_journal
.id or None,
513 'type': 'out_invoice',
514 'reference': order
.name
,
515 'partner_id': order
.partner_id
.id,
516 'comment': order
.note
or '',
517 'currency_id': order
.pricelist_id
.currency_id
.id, # considering partner's sale pricelist's currency
520 inv
.update(inv_ref
.onchange_partner_id(cr
, uid
, [], 'out_invoice', order
.partner_id
.id)['value'])
521 if not inv
.get('account_id', None):
522 inv
['account_id'] = acc
523 for line
in order
.lines
:
525 #'invoice_id': inv_id,
526 'product_id': line
.product_id
.id,
527 'quantity': line
.qty
,
529 inv_name
= product_obj
.name_get(cr
, uid
, [line
.product_id
.id], context
=context
)[0][1]
530 inv_line
.update(inv_line_ref
.product_id_change(cr
, uid
, [],
532 line
.product_id
.uom_id
.id,
533 line
.qty
, partner_id
= order
.partner_id
.id,
534 fposition_id
=order
.partner_id
.property_account_position
.id)['value'])
535 if line
.product_id
.description_sale
:
536 inv_line
['note'] = line
.product_id
.description_sale
537 inv_line
['price_unit'] = line
.price_unit
538 inv_line
['discount'] = line
.discount
539 inv_line
['name'] = inv_name
540 inv_line
['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line
)\
541 and [(6, 0, inv_line
['invoice_line_tax_id'])] or []
542 #inv_line_ref.create(cr, uid, inv_line, context=context)
543 inv
['invoice_line'].append((0, 0, inv_line
))
544 inv_id
= inv_ref
.create(cr
, uid
, inv
, context
=context
)
546 self
.write(cr
, uid
, [order
.id], {'invoice_id': inv_id
, 'state': 'invoiced'}, context
=context
)
547 inv_ref
.confirm_paid(cr
, uid
, [inv_id
], context
=context
)
548 inv_ids
.append(inv_id
)
549 inv_ref
.button_reset_taxes(cr
, uid
, [inv_id
], context
=context
)
550 wf_service
.trg_validate(uid
, 'pos.order', order
.id, 'invoice', cr
)
552 if not inv_ids
: return {}
554 mod_obj
= self
.pool
.get('ir.model.data')
555 res
= mod_obj
.get_object_reference(cr
, uid
, 'account', 'invoice_form')
556 res_id
= res
and res
[1] or False
558 'name': _('Customer Invoice'),
562 'res_model': 'account.invoice',
563 'context': "{'type':'out_invoice'}",
564 'type': 'ir.actions.act_window',
567 'res_id': inv_ids
and inv_ids
[0] or False,
570 def write(self
, cr
, uid
, ids
, vals
, context
=None):
571 print("DEV: [pos_membership] [pos_order] [write]: ids=%s vals=%s" % (str(ids
), str(vals
)))
572 pos_order_obj
= self
.pool
.get('pos.order')
573 res
= super(pos_order
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
574 print("DEV: [pos_membership] [pos_order] [write]: res=%s" % str(res
))
577 def create(self
, cr
, uid
, vals
, context
=None):
578 print("DEV: [pos_membership] [pos_order] [create]: vals=%s" % (str(vals
)))
579 pos_order_obj
= self
.pool
.get('pos.order')
580 res
= super(pos_order
, self
).create(cr
, uid
, vals
, context
=context
)
581 print("DEV: [pos_membership] [pos_order] [create]: res=%s" % (str(res
)))
586 class pos_order_line(osv
.osv
):
587 _inherit
= 'pos.order.line'
589 def write(self
, cr
, uid
, ids
, vals
, context
=None):
590 print("DEV: [pos_membership] [pos_order_line] [write]: ids=%s vals=%s context=%s" % (str(ids
), str(vals
), str(context
)))
591 member_line_obj
= self
.pool
.get('membership.membership_line')
592 res
= super(pos_order_line
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
593 print ("DEV: [pos_membership] [pos_order_line] [write] [super] : res=%s" % str(res
))
594 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
595 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
596 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
597 date_from
= line
.product_id
.membership_date_from
598 date_to
= line
.product_id
.membership_date_to
599 if line
.order_id
.date_order
> date_from
and \
600 line
.order_id
.date_order
< date_to
:
601 date_from
= line
.order_id
.date_order
602 if line
.product_id
.membership_date2date
:
603 date_from
= ('date_from' in context
604 and context
['date_from']
605 and datetime
.strptime(context
['date_from'], "%Y-%m-%d")
607 date_to
= date_from
+ relativedelta(months
= +12) # TODO: parameterize this delta?
608 date_from
= date_from
.strftime("%Y-%m-%d")
609 date_to
= date_to
.strftime("%Y-%m-%d")
610 print ("DEV: [pos_membership] [write] date_from: %s" % str(date_from
))
611 print ("DEV: [pos_membership] [write] date_to : %s" % str(date_to
))
612 member_line_obj
.create(cr
, uid
613 , { 'partner': line
.order_id
.partner_id
and line
.order_id
.partner_id
.id or False
614 , 'membership_id': line
.product_id
.id
615 , 'member_price': line
.price_unit
616 , 'date': time
.strftime('%Y-%m-%d')
617 , 'date_from': date_from
619 , 'pos_order_line': line
.id
622 if line
.product_id
.membership_grouped
:
623 if line
.order_id
.partner_id
.associate_members
:
624 associate_member_line_ids
= member_line_obj
.search(cr
, uid
625 , [ ('pos_order_line', '=', line
.id)
626 , ('partner', '!=', line
.order_id
.partner_id
.id)
629 for associate_member_line
in member_line_obj
.browse(cr
, uid
, associate_member_line_ids
, context
=context
):
630 print ("DEV: [pos_membership] [write] [associate] date_from: %s" % str(date_from
))
631 print ("DEV: [pos_membership] [write] [associate] date_to : %s" % str(date_to
))
632 member_line_obj
.write(cr
, uid
, associate_member_line
.id
633 , {'date_from': date_from
638 print("DEV: mettre une contrainte pour l'objet\
639 membership.membership_line interdisant les\
640 adhésions groupées reliées à des partenaires\
641 sans membres associés")
643 associate_member_line_ids
= member_line_obj
.search(cr
, uid
644 , [ ('pos_order_line', '=', line
.id)
645 , ('partner', '!=', line
.order_id
.partner_id
.id)
648 member_line_obj
.unlink(cr
, uid
, associate_member_line_ids
, context
=context
)
650 #Define member ident if it's necessary
651 partners
= [line
.order_id
.partner_id
]
652 if line
.order_id
.partner_id
.associate_members
:
653 partners
.extend(line
.order_id
.partner_id
.associate_members
)
655 if not i
.member_ident
:
656 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
657 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
658 if line
.product_id
and not line
.product_id
.membership
and ml_ids
:
659 # Product line has changed to a non membership product
660 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
661 print("DEV: [pos_membership] [pos_order_line] [write]: res=%s" % str(res
))
664 def unlink(self
, cr
, uid
, ids
, context
=None):
665 """Remove Membership Line Record for Account Invoice Line
667 member_line_obj
= self
.pool
.get('membership.membership_line')
669 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', id)], context
=context
)
670 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
671 return super(pos_order_line
, self
).unlink(cr
, uid
, ids
, context
=context
)
673 def create(self
, cr
, uid
, vals
, context
=None):
674 member_line_obj
= self
.pool
.get('membership.membership_line')
675 print("DEV: [pos_membership] [pos_order_line] [create]: vals=%s context=%s" % (str(vals
), str(context
)))
676 res
= super(pos_order_line
, self
).create(cr
, uid
, vals
, context
=context
)
677 print ("DEV: [pos_membership] [pos_order_line] [create] [super] : res=%s" % str(res
))
678 line
= self
.browse(cr
, uid
, res
, context
=context
)
680 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
681 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
682 date_from
= line
.product_id
.membership_date_from
683 date_to
= line
.product_id
.membership_date_to
684 if line
.order_id
.date_order
> date_from
and line
.order_id
.date_order
< date_to
:
685 date_from
= line
.order_id
.date_order
686 if line
.product_id
.membership_date2date
:
687 date_from
= ('date_from' in context
688 and context
.get('date_from')
689 and datetime
.strptime(context
.get('date_from'), "%Y-%m-%d")
691 date_to
= date_from
+ relativedelta(days
= +364) # TODO: parameterize this delta?
692 date_from
= date_from
.strftime("%Y-%m-%d")
693 date_to
= date_to
.strftime("%Y-%m-%d")
694 print ("DEV: [pos_membership] [pos_order_line] [create] date_from: %s" % str(date_from
))
695 print ("DEV: [pos_membership] [pos_order_line] [create] date_to : %s" % str(date_to
))
696 member_line_obj
.create(cr
, uid
, {
697 'partner': line
.order_id
.partner_id
and line
.order_id
.partner_id
.id or False,
698 'membership_id': line
.product_id
.id,
699 'member_price': line
.price_unit
,
700 'date': time
.strftime('%Y-%m-%d'),
701 'date_from': date_from
,
703 'pos_order_line': line
.id,
705 partners
= [line
.order_id
.partner_id
]
706 if line
.product_id
.membership_grouped
and line
.order_id
.partner_id
.associate_members
:
707 partners
.extend(line
.order_id
.partner_id
.associate_members
)
708 #Adding membership lines just for associate partners
709 for associate_member
in line
.order_id
.partner_id
.associate_members
:
710 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_from: %s" % str(date_from
))
711 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_to : %s" % str(date_to
))
712 member_line_obj
.create(cr
, uid
, {
713 'partner': associate_member
.id,
714 'membership_id': line
.product_id
.id,
715 'member_price': line
.price_unit
,
716 'date': time
.strftime('%Y-%m-%d'),
717 'date_from': date_from
,
719 'pos_order_line': line
.id,
721 elif line
.product_id
.membership_grouped
and not line
.order_id
.partner_id
.associate_members
:
722 raise osv
.except_osv(_('Error!!!'), _('You try to order grouped membership product to a partner who hasn\'t associated partners.'))
723 #Define member ident if it's necessary
726 print ("\033[7mXXX: [pos_membership] [pos_order_line] [create] : pos_order_line has no partner_id!\033[0m")
728 if not i
.member_ident
:
729 print ("DEV: [pos_membership] [pos_order_line] [create] [partners] : i=%s i.id=%s" % (str(i
), str(i
.id)))
730 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
731 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
732 print ("DEV: [pos_membership] [pos_order_line] [create] : return=%s" % str(res
))
737 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: