1
|
from datetime import datetime
|
2
|
|
3
|
from qommon.cron import CronJob
|
4
|
from qommon.publisher import get_publisher_class
|
5
|
from qommon import get_logger
|
6
|
|
7
|
from wcs.users import User
|
8
|
|
9
|
from abelium_domino_ui import (get_client, is_activated, get_invoice_regie,
|
10
|
abelium_domino_ws)
|
11
|
from payments import Invoice, Transaction
|
12
|
|
13
|
DOMINO_ID_PREFIX = 'DOMINO-'
|
14
|
|
15
|
def synchronize_domino(publisher):
|
16
|
regie = get_invoice_regie(publisher)
|
17
|
logger = get_logger()
|
18
|
if not is_activated(publisher) or not regie:
|
19
|
return
|
20
|
client = get_client(publisher)
|
21
|
client.clear_cache()
|
22
|
users = User.values()
|
23
|
users_by_mail = dict(((user.email, user) for user in users))
|
24
|
users_by_code_interne = {}
|
25
|
for user in users:
|
26
|
if hasattr(user, 'abelium_domino_code_famille'):
|
27
|
users_by_code_interne[user.abelium_domino_code_famille] = user
|
28
|
try:
|
29
|
invoices = client.invoices
|
30
|
except abelium_domino_ws.DominoException, e:
|
31
|
logger.debug('domino cron: failure to retrieve invoice list from domino '
|
32
|
'for synchronization [error:%s]', e)
|
33
|
return
|
34
|
# import new invoices
|
35
|
logger.debug('domino cron: retrieved %i invoices', len(invoices))
|
36
|
for invoice_id, invoice in invoices.iteritems():
|
37
|
user = None
|
38
|
if invoice.family.code_interne in users_by_code_interne:
|
39
|
user = users_by_code_interne[invoice.family.code_interne]
|
40
|
if user is None:
|
41
|
for email in (invoice.family.email_pere, invoice.family.email_mere,
|
42
|
invoice.family.adresse_internet):
|
43
|
user = users_by_mail.get(email)
|
44
|
if user:
|
45
|
break
|
46
|
else:
|
47
|
continue
|
48
|
external_id = '%s%s' % (DOMINO_ID_PREFIX, invoice.id)
|
49
|
payment_invoice = Invoice.get_on_index(external_id, 'external_id', ignore_errors=True)
|
50
|
if payment_invoice:
|
51
|
continue
|
52
|
payment_invoice = Invoice()
|
53
|
payment_invoice.user_id = user.id
|
54
|
payment_invoice.external_id = external_id
|
55
|
payment_invoice.regie_id = regie.id
|
56
|
payment_invoice.formdef_id = None
|
57
|
payment_invoice.formdata_id = None
|
58
|
payment_invoice.amount = invoice.montant
|
59
|
payment_invoice.date = invoice.creation
|
60
|
payment_invoice.domino_synchro_date = datetime.now()
|
61
|
payment_invoice.store()
|
62
|
logger.info('domino cron: remote invoice %s for family %s added to user %s invoices with id %s',
|
63
|
invoice.id, invoice.family.id, user.id, payment_invoice.id)
|
64
|
|
65
|
# update invoices
|
66
|
invoices_ids = dict(invoices.iteritems())
|
67
|
for payment_invoice in Invoice.values():
|
68
|
if payment_invoice.external_id is None or not payment_invoice.external_id.startswith(DOMINO_ID_PREFIX):
|
69
|
continue # not a payment related to domino we skip
|
70
|
i = payment_invoice.external_id[len(DOMINO_ID_PREFIX):]
|
71
|
i = int(i)
|
72
|
invoice = invoices_ids.get(i)
|
73
|
if payment_invoice.paid:
|
74
|
if not invoice:
|
75
|
# invoice has been paid (locally or not) but remote invoice has
|
76
|
# been deleted do, we do nothing.
|
77
|
continue
|
78
|
if getattr(payment_invoice, 'domino_knows_its_paid', None) or getattr(payment_invoice, 'paid_by_domino', None):
|
79
|
# synchronization of payment already done, skip
|
80
|
continue
|
81
|
transactions = Transaction.get_with_indexed_value('invoice_ids', payment_invoice.id)
|
82
|
if not transactions:
|
83
|
logger.warning("domino cron: invoice %s is marked paid but does "
|
84
|
"not have any linked transaction.", payment_invoice.id)
|
85
|
details = '' # no details about the payment, problem
|
86
|
else:
|
87
|
details = repr(transactions[0].__dict__)
|
88
|
if invoice.montant != payment_invoice.amount:
|
89
|
pass # add warning logs
|
90
|
try:
|
91
|
client.pay_invoice([invoice], invoice.montant, details,
|
92
|
payment_invoice.paid_date)
|
93
|
except abelium_domino_ws.DominoException, e:
|
94
|
logger.error('domino cron: invoice %s has been paid, but the remote system '
|
95
|
'is unreachable, notification will be done again '
|
96
|
'later [error: %s]', invoice.id, e)
|
97
|
else:
|
98
|
# memorize the date of synchronization
|
99
|
payment_invoice.domino_knows_its_paid = datetime.now()
|
100
|
payment_invoice.store()
|
101
|
logger.info('domino cron: domino: invoice %s has been paid; remote system has been '
|
102
|
'notified', payment_invoice.id)
|
103
|
else: # unpaid
|
104
|
if not invoice:
|
105
|
logger.info('domino cron: remote invoice %s disapearred, so its '
|
106
|
'still-unpaid local counterpart invoice %s was deleted.',
|
107
|
i, payment_invoice.id)
|
108
|
payment_invoice.remove_self()
|
109
|
elif invoice.paid():
|
110
|
payment_invoice.paid = True
|
111
|
# cannot do better :(
|
112
|
payment_invoice.paid_date = datetime.now()
|
113
|
payment_invoice.paid_by_domino = True
|
114
|
payment_invoice.store()
|
115
|
logger.info('domino cron: remote invoice %s has beend paid, '
|
116
|
'local invoice %s of user %s is now marked as paid.',
|
117
|
invoice.id, payment_invoice.id, payment_invoice.user_id)
|
118
|
else: # not invoice.paid()
|
119
|
pass # still waiting for the payment
|
120
|
|
121
|
get_publisher_class().register_cronjob(CronJob(function=synchronize_domino,
|
122
|
hours=range(0, 24), minutes=range(0, 60)))
|