Project

General

Profile

Download (5.57 KB) Statistics
| Branch: | Tag: | Revision:

root / extra / modules / abelium_domino_synchro.py @ 84fd22a0

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)))
(2-2/32)