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 print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_pos_order]: ids=%s context=%s" % (str(ids
), str(context
)))
71 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
73 list_membership_line
+= member_line_obj
.search(cr
, uid
, [('pos_order_line', 'in', [ l
.id for l
in order
.lines
])], context
=context
)
75 # { 'class': 'pos.order'
76 # , 'ids': list_membership_line
78 res
= list_membership_line
79 print("DEV: [pos_membership] [membership_line] [_get_membership_lines_from_pos_order]: res=%s" % str(res
))
82 def _check_membership_date(self
, cr
, uid
, ids
, context
=None):
83 """Check if membership product is not in the past
84 @param self: The object pointer
85 @param cr: the current row, from the database cursor,
86 @param uid: the current user’s ID for security checks,
87 @param ids: List of Membership Line IDs
88 @param context: A standard dictionary for contextual values
92 SELECT MIN(ml.date_to - ai.date_invoice)
93 FROM membership_membership_line ml
94 JOIN account_invoice_line ail ON (
95 ml.account_invoice_line = ail.id
97 JOIN account_invoice ai ON (
98 ai.id = ail.invoice_id)
99 WHERE ml.id IN %s''', (tuple(ids
),))
102 if r
[0] and r
[0] < 0:
105 SELECT MIN(ml.date_to - ai.date_order)
106 FROM membership_membership_line ml
107 JOIN pos_order_line ail ON (
108 ml.pos_order_line = ail.id
110 JOIN pos_order ai ON (
111 ai.id = ail.order_id)
112 WHERE ml.id IN %s''', (tuple(ids
),))
115 if r
[0] and r
[0] < 0:
119 def _state(self
, cr
, uid
, ids
, name
, args
, context
=None):
120 """Compute the state lines
121 @param self: The object pointer
122 @param cr: the current row, from the database cursor,
123 @param uid: the current user’s ID for security checks,
124 @param ids: List of Membership Line IDs
125 @param name: Field Name
126 @param context: A standard dictionary for contextual values
127 @param return: Dictionary of state Value
130 print("DEV: [pos_membership] [membership_line] [_state]: name=%s ids=%s args=%s context=%s" % (str(name
), str(ids
), str(args
), str(context
)))
131 inv_obj
= self
.pool
.get('account.invoice')
132 ord_obj
= self
.pool
.get('pos.order')
133 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
135 SELECT i.state, i.id FROM
139 SELECT l.invoice_id FROM
140 account_invoice_line l WHERE
142 SELECT ml.account_invoice_line FROM
143 membership_membership_line ml WHERE
148 fetched
= cr
.fetchone()
152 if (istate
== 'draft') |
(istate
== 'proforma'):
154 elif istate
== 'open':
156 elif istate
== 'paid':
158 inv
= inv_obj
.browse(cr
, uid
, fetched
[1], context
=context
)
159 for payment
in inv
.payment_ids
:
160 if payment
.invoice
and payment
.invoice
.type == 'out_refund':
162 elif istate
== 'cancel':
167 SELECT i.state, i.id, i.partner_id FROM
171 SELECT l.order_id FROM
172 pos_order_line l WHERE
174 SELECT ml.pos_order_line FROM
175 membership_membership_line ml WHERE
180 fetched
= cr
.fetchone()
182 res
[line
.id] = 'canceled'
184 partner_id
= fetched
[2]
185 self
.write(cr
, uid
, line
.id, {'partner': partner_id
})
186 # NOTE: force une mise à jour du partner,
187 # car il n'y en a pas lors de la création du pos.order
188 # dans le PoS (pour le moment)
191 if (ostate
== 'paid') |
(ostate
== 'draft'):
193 elif (ostate
== 'done') |
(ostate
== 'invoiced'):
195 # XXX: regarder l'équivalent de out_refund pour un pos.order
196 print("DEV: [pos_membership] [membership_line] [_state]: paid: TODO")
197 #inv = ord_obj.browse(cr, uid, fetched[1], context=context)
198 #for payment in inv.payment_ids:
199 # if payment.invoice and payment.invoice.type == 'out_refund':
201 elif ostate
== 'cancel':
204 print("DEV: [pos_membership] [membership_line] [_state]: return=%s" % (str(res
)))
207 def write(self
, cr
, uid
, ids
, vals
, context
=None):
208 print("DEV: [pos_membership] [membership_line] [write]: ids=%s vals=%s" % (str(ids
), str(vals
)))
209 member_line_obj
= self
.pool
.get('membership.membership_line')
210 res
= super(membership_line
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
211 print("DEV: [pos_membership] [membership_line] [write]: res=%s" % str(res
))
214 def create(self
, cr
, uid
, vals
, context
=None):
215 print("DEV: [pos_membership] [membership_line] [create]: vals=%s" % (str(vals
)))
216 member_line_obj
= self
.pool
.get('membership.membership_line')
217 res
= super(membership_line
, self
).create(cr
, uid
, vals
, context
=context
)
218 print("DEV: [pos_membership] [membership_line] [create]: res=%s" % (str(res
)))
222 'pos_order_line': fields
.many2one('pos.order.line', 'POS Order line', readonly
=True),
223 'pos_order_id': fields
.related('pos_order_line', 'order_id', type='many2one', relation
='pos.order', string
='Order', readonly
=True),
224 'state': fields
.function(_state
,
225 string
='Membership Status', type='selection',
228 #'account.invoice': (_get_membership_lines_from_account_invoice, ['state'], 10),
229 # NOTE: déjà géré par membership.membership_line._get_membership_lines
230 'pos.order': (_get_membership_lines_from_pos_order
, ['state', 'partner_id'], 10),
231 'res.partner': (_get_partners
, ['membership_state'], 12),
232 }, help="""It indicates the membership status.
233 -Non Member: A member who has not applied for any membership.
234 -Cancelled Member: A member who has cancelled his membership.
235 -Old Member: A member whose membership date has expired.
236 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
237 -Invoiced Member: A member whose invoice has been created.
238 -Paid Member: A member who has paid the membership amount."""),
239 'company_id': fields
.related('account_invoice_line', 'invoice_id', 'company_id', type="many2one", relation
="res.company", string
="Company", readonly
=True, store
=True)
240 # XXX: pos_order_line a aussi un company_id
245 class Partner(osv
.osv
):
247 _inherit
= 'res.partner'
249 def _get_partner_id(self
, cr
, uid
, ids
, context
=None):
250 print("DEV: [pos_membership] [Partner] [_get_partner_id]: ids=%s context=%s" % (str(ids
), str(context
)))
251 member_line_obj
= self
.pool
.get('membership.membership_line')
252 res_obj
= self
.pool
.get('res.partner')
253 data_inv
= member_line_obj
.browse(cr
, uid
, ids
, context
=context
)
255 for data
in data_inv
:
256 list_partner
.append(data
.partner
.id)
259 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
261 print("DEV: [pos_membership] [Partner] [_get_partner_id]: res=%s" % (str(list_partner
)))
264 def _get_invoice_partner(self
, cr
, uid
, ids
, context
=None):
265 inv_obj
= self
.pool
.get('account.invoice')
266 res_obj
= self
.pool
.get('res.partner')
267 data_inv
= inv_obj
.browse(cr
, uid
, ids
, context
=context
)
269 for data
in data_inv
:
270 list_partner
.append(data
.partner_id
.id)
273 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
277 def _get_order_partner(self
, cr
, uid
, ids
, context
=None):
278 ord_obj
= self
.pool
.get('pos.order')
279 res_obj
= self
.pool
.get('res.partner')
280 data_ord
= ord_obj
.browse(cr
, uid
, ids
, context
=context
)
282 for data
in data_ord
:
283 list_partner
.append(data
.partner_id
.id)
286 ids2
= res_obj
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
290 def _membership_state(self
, cr
, uid
, ids
, name
, args
, context
=None):
291 """This Function return Membership State For Given Partner.
292 @param self: The object pointer
293 @param cr: the current row, from the database cursor,
294 @param uid: the current user’s ID for security checks,
295 @param ids: List of Partner IDs
296 @param name: Field Name
297 @param context: A standard dictionary for contextual values
298 @param return: Dictionary of Membership state Value
301 print("DEV: [pos_membership] [Partner] [_membership_state]: name=%s ids=%s args=%s context=%s" % (str(name
), str(ids
), str(args
), str(context
)))
304 today
= time
.strftime('%Y-%m-%d')
306 print("DEV: [pos_membership] [Partner] [_membership_state] id=%s" % (str(id)))
307 partner_data
= self
.browse(cr
, uid
, id, context
=context
)
308 if partner_data
.membership_cancel
and today
> partner_data
.membership_cancel
:
311 if partner_data
.membership_stop
and today
> partner_data
.membership_stop
:
315 print("DEV: [pos_membership] [Partner] [_membership_state] [partner_data] [member_lines] [test]")
316 if partner_data
.member_lines
:
317 print("DEV: [pos_membership] [Partner] [_membership_state] [partner_data] [member_lines]" % ())
318 for mline
in partner_data
.member_lines
:
319 print("DEV: [pos_membership] [Partner] [_membership_state] [mline]: id=%s" % str(mline
.id))
320 if mline
.date_to
>= today
:
321 if mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
:
322 istate
= mline
.account_invoice_line
.invoice_id
.state
323 print("DEV: [pos_membership] [Partner] [_membership_state] [account_invoice_line]: id=%s istate=%s" % (str(mline
.account_invoice_line
.invoice_id
.id), str(istate
)))
326 inv
= mline
.account_invoice_line
.invoice_id
327 for payment
in inv
.payment_ids
:
328 if payment
.invoice
.type == 'out_refund':
331 elif istate
== 'open' and s
!=0:
333 elif istate
== 'cancel' and s
!=0 and s
!=1:
335 elif (istate
== 'draft' or istate
== 'proforma') and s
!=0 and s
!=1:
337 elif mline
.pos_order_line
and mline
.pos_order_line
.order_id
:
338 ostate
= mline
.pos_order_line
.order_id
.state
339 print("DEV: [pos_membership] [Partner] [_membership_state] [pos_order_line]: id=%s ostate=%s" % (str(mline
.pos_order_line
.order_id
.id), str(ostate
)))
340 if ostate
== 'paid' and s
!=0 and s
!=1:
342 if ostate
== 'invoiced':
346 # XXX: regarder l'équivalent de out_refund pour un pos.order
347 print("DEV: [pos_membership] [partner] [_membership_state]: paid: TODO")
348 #inv = mline.pos_order_line.order_id
349 #for payment in inv.payment_ids:
350 # if payment.invoice.type == 'out_refund':
353 elif ostate
== 'open' and s
!=0:
354 # XXX: 1 donne invoiced, c'est pitet pas bon
355 print("DEV: [pos_membership] [partner] [_membership_state]: invoiced: TODO")
357 elif ostate
== 'cancel' and s
!=0 and s
!=1:
359 elif ostate
== 'draft' and s
!=0 and s
!=1:
362 for mline
in partner_data
.member_lines
:
363 if mline
.date_from
< today
and \
364 mline
.date_to
< today
and \
365 mline
.date_from
<= mline
.date_to
and \
366 ( (mline
.account_invoice_line
and mline
.account_invoice_line
.invoice_id
.state
) == 'paid' or \
367 ( mline
.pos_order_line
and \
368 ( mline
.pos_order_line
.order_id
.state
== 'paid' or \
369 mline
.pos_order_line
.order_id
.state
== 'done' or \
370 mline
.pos_order_line
.order_id
.state
== 'invoiced' ))):
386 if partner_data
.free_member
and s
!=0:
388 if partner_data
.associate_member
:
389 res_state
= self
._membership
_state
(cr
, uid
, [partner_data
.associate_member
.id], name
, args
, context
=context
)
390 res
[id] = res_state
[partner_data
.associate_member
.id]
391 print("DEV: [pos_membership] [Partner] [_membership_state]: res=%s" % (str(res
)))
394 def _membership_date(self
, cr
, uid
, ids
, name
, args
, context
=None):
395 """Return date of membership"""
398 member_line_obj
= self
.pool
.get('membership.membership_line')
399 print("DEV: [pos_membership] [Partner] [_membership_date]: ids=%s" % (str(ids
)))
400 for partner
in self
.browse(cr
, uid
, ids
, context
=context
):
401 if partner
.associate_member
:
402 partner_id
= partner
.associate_member
.id
404 partner_id
= partner
.id
406 'membership_start': False,
407 'membership_stop': False,
408 'membership_cancel': False
410 if name
== 'membership_start':
411 line_id
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
412 limit
=1, order
='date_from', context
=context
)
414 res
[partner
.id]['membership_start'] = member_line_obj
.read(cr
, uid
, line_id
[0],
415 ['date_from'], context
=context
)['date_from']
416 print("DEV: [pos_membership] [Partner] [_membership_date] [membership_start]: ids=%s date=%s" % (str(ids
), str(res
[partner
.id]['membership_start'])))
418 if name
== 'membership_stop':
419 line_id1
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner_id
),('date_cancel','=',False)],
420 limit
=1, order
='date_to desc', context
=context
)
422 res
[partner
.id]['membership_stop'] = member_line_obj
.read(cr
, uid
, line_id1
[0],
423 ['date_to'], context
=context
)['date_to']
424 print("DEV: [pos_membership] [Partner] [_membership_date] [membership_stop]: ids=%s date=%s" % (str(ids
), str(res
[partner
.id]['membership_stop'])))
426 if name
== 'membership_cancel':
427 if partner
.membership_state
== 'canceled':
428 line_id2
= member_line_obj
.search(cr
, uid
, [('partner', '=', partner
.id)], limit
=1, order
='date_cancel', context
=context
)
430 res
[partner
.id]['membership_cancel'] = member_line_obj
.read(cr
, uid
, line_id2
[0], ['date_cancel'], context
=context
)['date_cancel']
431 print("DEV: [pos_membership] [Partner] [_membership_date] [membership_cancel]: ids=%s date=%s" % (str(ids
), str(res
[partner
.id]['membership_cancel'])))
432 print("DEV: [pos_membership] [Partner] [_membership_date]: res=%s" % (str(res
)))
435 def _get_partners(self
, cr
, uid
, ids
, context
=None):
438 ids2
= self
.search(cr
, uid
, [('associate_member', 'in', ids2
)], context
=context
)
442 def __get_membership_state(self
, *args
, **kwargs
):
443 return self
._membership
_state
(*args
, **kwargs
)
446 'membership_state': fields
.function(
447 __get_membership_state
,
448 string
= 'Current Membership Status', type = 'selection',
451 # NOTE: il est important que la priorité soit plus grande
452 # que les membership_{start,stop,cancel}
453 # car _membership_state s'en sert et doit donc les trouver à jour.
454 'account.invoice': (_get_invoice_partner
, ['state'], 20),
455 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 20),
456 'membership.membership_line': (_get_partner_id
, ['state'], 20),
457 'res.partner': (_get_partners
, ['free_member', 'membership_state', 'associate_member'], 20)
458 }, help="""It indicates the membership state.
459 -Non Member: A partner who has not applied for any membership.
460 -Cancelled Member: A member who has cancelled his membership.
461 -Old Member: A member whose membership date has expired.
462 -Waiting Member: A member who has applied for the membership and whose invoice is going to be created.
463 -Invoiced Member: A member whose invoice has been created.
464 -Paying member: A member who has paid the membership fee."""),
465 'membership_start': fields
.function(
466 _membership_date
, multi
= 'membeship_start',
467 string
= 'Membership Start Date', type = 'date',
469 'account.invoice': (_get_invoice_partner
, ['state'], 10),
470 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 10),
471 'membership.membership_line': (_get_partner_id
, ['state'], 10),
472 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
473 }, help="Date from which membership becomes active."),
474 'membership_stop': fields
.function(
476 string
= 'Membership End Date', type='date', multi
='membership_stop',
478 'account.invoice': (_get_invoice_partner
, ['state'], 10),
479 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 10),
480 'membership.membership_line': (_get_partner_id
, ['state'], 10),
481 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
482 }, help="Date until which membership remains active."),
483 'membership_cancel': fields
.function(
485 string
= 'Cancel Membership Date', type='date', multi
='membership_cancel',
487 'account.invoice': (_get_invoice_partner
, ['state'], 11),
488 'pos.order': (_get_order_partner
, ['state', 'partner_id'], 11),
489 'membership.membership_line': (_get_partner_id
, ['state'], 10),
490 'res.partner': (lambda self
, cr
, uid
, ids
, c
={}: ids
, ['free_member'], 10)
491 }, help="Date on which membership has been cancelled"),
496 class pos_order(osv
.osv
):
497 _inherit
= 'pos.order'
499 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py
500 def action_invoice(self
, cr
, uid
, ids
, context
=None):
501 print ("DEV: [pos_membership] [pos_order] [action_invoice]")
502 wf_service
= netsvc
.LocalService("workflow")
503 inv_ref
= self
.pool
.get('account.invoice')
504 inv_line_ref
= self
.pool
.get('account.invoice.line')
505 product_obj
= self
.pool
.get('product.product')
508 for order
in self
.pool
.get('pos.order').browse(cr
, uid
, ids
, context
=context
):
510 inv_ids
.append(order
.invoice_id
.id)
513 if not order
.partner_id
:
514 raise osv
.except_osv(_('Error!'), _('Please provide a partner for the sale.'))
516 acc
= order
.partner_id
.property_account_receivable
.id
517 # XXX: copied from openerp/addons/point_of_sale/point_of_sale.py to fix account.invoice.line creation
520 'origin': order
.name
,
522 'journal_id': order
.sale_journal
.id or None,
523 'type': 'out_invoice',
524 'reference': order
.name
,
525 'partner_id': order
.partner_id
.id,
526 'comment': order
.note
or '',
527 'currency_id': order
.pricelist_id
.currency_id
.id, # considering partner's sale pricelist's currency
530 inv
.update(inv_ref
.onchange_partner_id(cr
, uid
, [], 'out_invoice', order
.partner_id
.id)['value'])
531 if not inv
.get('account_id', None):
532 inv
['account_id'] = acc
533 for line
in order
.lines
:
535 #'invoice_id': inv_id,
536 'product_id': line
.product_id
.id,
537 'quantity': line
.qty
,
539 inv_name
= product_obj
.name_get(cr
, uid
, [line
.product_id
.id], context
=context
)[0][1]
540 inv_line
.update(inv_line_ref
.product_id_change(cr
, uid
, [],
542 line
.product_id
.uom_id
.id,
543 line
.qty
, partner_id
= order
.partner_id
.id,
544 fposition_id
=order
.partner_id
.property_account_position
.id)['value'])
545 if line
.product_id
.description_sale
:
546 inv_line
['note'] = line
.product_id
.description_sale
547 inv_line
['price_unit'] = line
.price_unit
548 inv_line
['discount'] = line
.discount
549 inv_line
['name'] = inv_name
550 inv_line
['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line
)\
551 and [(6, 0, inv_line
['invoice_line_tax_id'])] or []
552 #inv_line_ref.create(cr, uid, inv_line, context=context)
553 inv
['invoice_line'].append((0, 0, inv_line
))
554 inv_id
= inv_ref
.create(cr
, uid
, inv
, context
=context
)
556 self
.write(cr
, uid
, [order
.id], {'invoice_id': inv_id
, 'state': 'invoiced'}, context
=context
)
557 inv_ref
.confirm_paid(cr
, uid
, [inv_id
], context
=context
)
558 inv_ids
.append(inv_id
)
559 inv_ref
.button_reset_taxes(cr
, uid
, [inv_id
], context
=context
)
560 wf_service
.trg_validate(uid
, 'pos.order', order
.id, 'invoice', cr
)
562 if not inv_ids
: return {}
564 mod_obj
= self
.pool
.get('ir.model.data')
565 res
= mod_obj
.get_object_reference(cr
, uid
, 'account', 'invoice_form')
566 res_id
= res
and res
[1] or False
568 'name': _('Customer Invoice'),
572 'res_model': 'account.invoice',
573 'context': "{'type':'out_invoice'}",
574 'type': 'ir.actions.act_window',
577 'res_id': inv_ids
and inv_ids
[0] or False,
580 def write(self
, cr
, uid
, ids
, vals
, context
=None):
581 print("DEV: [pos_membership] [pos_order] [write]: ids=%s vals=%s" % (str(ids
), str(vals
)))
582 pos_order_obj
= self
.pool
.get('pos.order')
583 res
= super(pos_order
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
584 print("DEV: [pos_membership] [pos_order] [write]: res=%s" % str(res
))
587 def create(self
, cr
, uid
, vals
, context
=None):
588 print("DEV: [pos_membership] [pos_order] [create]: vals=%s" % (str(vals
)))
589 pos_order_obj
= self
.pool
.get('pos.order')
590 res
= super(pos_order
, self
).create(cr
, uid
, vals
, context
=context
)
591 print("DEV: [pos_membership] [pos_order] [create]: res=%s" % (str(res
)))
596 class pos_order_line(osv
.osv
):
597 _inherit
= 'pos.order.line'
599 def write(self
, cr
, uid
, ids
, vals
, context
=None):
600 print("DEV: [pos_membership] [pos_order_line] [write]: ids=%s vals=%s context=%s" % (str(ids
), str(vals
), str(context
)))
601 member_line_obj
= self
.pool
.get('membership.membership_line')
602 res
= super(pos_order_line
, self
).write(cr
, uid
, ids
, vals
, context
=context
)
603 print ("DEV: [pos_membership] [pos_order_line] [write] [super] : res=%s" % str(res
))
604 for line
in self
.browse(cr
, uid
, ids
, context
=context
):
605 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
606 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
607 date_from
= line
.product_id
.membership_date_from
608 date_to
= line
.product_id
.membership_date_to
609 if line
.order_id
.date_order
> date_from
and \
610 line
.order_id
.date_order
< date_to
:
611 date_from
= line
.order_id
.date_order
612 if line
.product_id
.membership_date2date
:
613 date_from
= ('date_from' in context
614 and context
['date_from']
615 and datetime
.strptime(context
['date_from'], "%Y-%m-%d")
617 date_to
= date_from
+ relativedelta(months
= +12) # TODO: parameterize this delta?
618 date_from
= date_from
.strftime("%Y-%m-%d")
619 date_to
= date_to
.strftime("%Y-%m-%d")
620 print ("DEV: [pos_membership] [write] date_from: %s" % str(date_from
))
621 print ("DEV: [pos_membership] [write] date_to : %s" % str(date_to
))
622 member_line_obj
.create(cr
, uid
623 , { 'partner': line
.order_id
.partner_id
and line
.order_id
.partner_id
.id or False
624 , 'membership_id': line
.product_id
.id
625 , 'member_price': line
.price_unit
626 , 'date': time
.strftime('%Y-%m-%d')
627 , 'date_from': date_from
629 , 'pos_order_line': line
.id
632 if line
.product_id
.membership_grouped
:
633 if line
.order_id
.partner_id
.associate_members
:
634 associate_member_line_ids
= member_line_obj
.search(cr
, uid
635 , [ ('pos_order_line', '=', line
.id)
636 , ('partner', '!=', line
.order_id
.partner_id
.id)
639 for associate_member_line
in member_line_obj
.browse(cr
, uid
, associate_member_line_ids
, context
=context
):
640 print ("DEV: [pos_membership] [write] [associate] date_from: %s" % str(date_from
))
641 print ("DEV: [pos_membership] [write] [associate] date_to : %s" % str(date_to
))
642 member_line_obj
.write(cr
, uid
, associate_member_line
.id
643 , {'date_from': date_from
648 print("DEV: mettre une contrainte pour l'objet\
649 membership.membership_line interdisant les\
650 adhésions groupées reliées à des partenaires\
651 sans membres associés")
653 associate_member_line_ids
= member_line_obj
.search(cr
, uid
654 , [ ('pos_order_line', '=', line
.id)
655 , ('partner', '!=', line
.order_id
.partner_id
.id)
658 member_line_obj
.unlink(cr
, uid
, associate_member_line_ids
, context
=context
)
660 #Define member ident if it's necessary
661 partners
= [line
.order_id
.partner_id
]
662 if line
.order_id
.partner_id
.associate_members
:
663 partners
.extend(line
.order_id
.partner_id
.associate_members
)
665 if not i
.member_ident
:
666 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
667 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
668 if line
.product_id
and not line
.product_id
.membership
and ml_ids
:
669 # Product line has changed to a non membership product
670 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
671 print("DEV: [pos_membership] [pos_order_line] [write]: res=%s" % str(res
))
674 def unlink(self
, cr
, uid
, ids
, context
=None):
675 """Remove Membership Line Record for Account Invoice Line
677 member_line_obj
= self
.pool
.get('membership.membership_line')
679 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', id)], context
=context
)
680 member_line_obj
.unlink(cr
, uid
, ml_ids
, context
=context
)
681 return super(pos_order_line
, self
).unlink(cr
, uid
, ids
, context
=context
)
683 def create(self
, cr
, uid
, vals
, context
=None):
684 member_line_obj
= self
.pool
.get('membership.membership_line')
685 print("DEV: [pos_membership] [pos_order_line] [create]: vals=%s context=%s" % (str(vals
), str(context
)))
686 res
= super(pos_order_line
, self
).create(cr
, uid
, vals
, context
=context
)
687 print ("DEV: [pos_membership] [pos_order_line] [create] [super] : res=%s" % str(res
))
688 line
= self
.browse(cr
, uid
, res
, context
=context
)
690 ml_ids
= member_line_obj
.search(cr
, uid
, [('pos_order_line', '=', line
.id)], context
=context
)
691 if line
.product_id
and line
.product_id
.membership
and not ml_ids
:
692 date_from
= line
.product_id
.membership_date_from
693 date_to
= line
.product_id
.membership_date_to
694 if line
.order_id
.date_order
> date_from
and line
.order_id
.date_order
< date_to
:
695 date_from
= line
.order_id
.date_order
696 if line
.product_id
.membership_date2date
:
697 date_from
= ('date_from' in context
698 and context
.get('date_from')
699 and datetime
.strptime(context
.get('date_from'), "%Y-%m-%d")
701 date_to
= date_from
+ relativedelta(days
= +364) # TODO: parameterize this delta?
702 date_from
= date_from
.strftime("%Y-%m-%d")
703 date_to
= date_to
.strftime("%Y-%m-%d")
704 print ("DEV: [pos_membership] [pos_order_line] [create] date_from: %s" % str(date_from
))
705 print ("DEV: [pos_membership] [pos_order_line] [create] date_to : %s" % str(date_to
))
706 member_line_obj
.create(cr
, uid
, {
707 'partner': line
.order_id
.partner_id
and line
.order_id
.partner_id
.id or False,
708 'membership_id': line
.product_id
.id,
709 'member_price': line
.price_unit
,
710 'date': time
.strftime('%Y-%m-%d'),
711 'date_from': date_from
,
713 'pos_order_line': line
.id,
715 partners
= [line
.order_id
.partner_id
]
716 if line
.product_id
.membership_grouped
and line
.order_id
.partner_id
.associate_members
:
717 partners
.extend(line
.order_id
.partner_id
.associate_members
)
718 #Adding membership lines just for associate partners
719 for associate_member
in line
.order_id
.partner_id
.associate_members
:
720 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_from: %s" % str(date_from
))
721 print ("DEV: [pos_membership] [pos_order_line] [create] [associate] date_to : %s" % str(date_to
))
722 member_line_obj
.create(cr
, uid
, {
723 'partner': associate_member
.id,
724 'membership_id': line
.product_id
.id,
725 'member_price': line
.price_unit
,
726 'date': time
.strftime('%Y-%m-%d'),
727 'date_from': date_from
,
729 'pos_order_line': line
.id,
731 elif line
.product_id
.membership_grouped
and not line
.order_id
.partner_id
.associate_members
:
732 raise osv
.except_osv(_('Error!!!'), _('You try to order grouped membership product to a partner who hasn\'t associated partners.'))
733 #Define member ident if it's necessary
736 print ("\033[7mXXX: [pos_membership] [pos_order_line] [create] : pos_order_line has no partner_id!\033[0m")
738 if not i
.member_ident
:
739 print ("DEV: [pos_membership] [pos_order_line] [create] [partners] : i=%s i.id=%s" % (str(i
), str(i
.id)))
740 mbr_id
= self
.pool
.get('ir.sequence').get(cr
, uid
, 'member_ident')
741 self
.pool
.get('res.partner').write(cr
, uid
, i
.id, {'member_ident': mbr_id
})
742 print ("DEV: [pos_membership] [pos_order_line] [create] : return=%s" % str(res
))
747 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: