Package Gnumed :: Package business :: Module gmBilling
[frames] | no frames]

Source Code for Module Gnumed.business.gmBilling

  1  # -*- coding: utf-8 -*- 
  2  """Billing code. 
  3   
  4  Copyright: authors 
  5  """ 
  6  #============================================================ 
  7  __author__ = "Nico Latzer <nl@mnet-online.de>, Karsten Hilbert <Karsten.Hilbert@gmx.net>" 
  8  __license__ = 'GPL v2 or later (details at http://www.gnu.org)' 
  9   
 10  import sys 
 11  import logging 
 12   
 13   
 14  if __name__ == '__main__': 
 15          sys.path.insert(0, '../../') 
 16  from Gnumed.pycommon import gmPG2 
 17  from Gnumed.pycommon import gmBusinessDBObject 
 18  from Gnumed.pycommon import gmTools 
 19  from Gnumed.pycommon import gmDateTime 
 20  from Gnumed.business import gmDemographicRecord 
 21  from Gnumed.business import gmDocuments 
 22   
 23  _log = logging.getLogger('gm.bill') 
 24   
 25  INVOICE_DOCUMENT_TYPE = 'invoice' 
 26  #============================================================ 
 27  # billables 
 28  #------------------------------------------------------------ 
 29  _SQL_get_billable_fields = "SELECT * FROM ref.v_billables WHERE %s" 
 30   
31 -class cBillable(gmBusinessDBObject.cBusinessDBObject):
32 """Items which can be billed to patients.""" 33 34 _cmd_fetch_payload = _SQL_get_billable_fields % "pk_billable = %s" 35 _cmds_store_payload = [ 36 """UPDATE ref.billable SET 37 fk_data_source = %(pk_data_source)s, 38 code = %(billable_code)s, 39 term = %(billable_description)s, 40 comment = gm.nullify_empty_string(%(comment)s), 41 amount = %(raw_amount)s, 42 currency = %(currency)s, 43 vat_multiplier = %(vat_multiplier)s, 44 active = %(active)s 45 --, discountable = %(discountable)s 46 WHERE 47 pk = %(pk_billable)s 48 AND 49 xmin = %(xmin_billable)s 50 RETURNING 51 xmin AS xmin_billable 52 """] 53 54 _updatable_fields = [ 55 'billable_code', 56 'billable_description', 57 'raw_amount', 58 'vat_multiplier', 59 'comment', 60 'currency', 61 'active', 62 'pk_data_source' 63 ] 64 #--------------------------------------------------------
65 - def format(self):
66 txt = '%s [#%s]\n\n' % ( 67 gmTools.bool2subst ( 68 self._payload[self._idx['active']], 69 _('Active billable item'), 70 _('Inactive billable item') 71 ), 72 self._payload[self._idx['pk_billable']] 73 ) 74 txt += ' %s: %s\n' % ( 75 self._payload[self._idx['billable_code']], 76 self._payload[self._idx['billable_description']] 77 ) 78 txt += _(' %(curr)s%(raw_val)s + %(perc_vat)s%% VAT = %(curr)s%(val_w_vat)s\n') % { 79 'curr': self._payload[self._idx['currency']], 80 'raw_val': self._payload[self._idx['raw_amount']], 81 'perc_vat': self._payload[self._idx['vat_multiplier']] * 100, 82 'val_w_vat': self._payload[self._idx['amount_with_vat']] 83 } 84 txt += ' %s %s%s (%s)' % ( 85 self._payload[self._idx['catalog_short']], 86 self._payload[self._idx['catalog_version']], 87 gmTools.coalesce(self._payload[self._idx['catalog_language']], '', ' - %s'), 88 self._payload[self._idx['catalog_long']] 89 ) 90 txt += gmTools.coalesce(self._payload[self._idx['comment']], '', '\n %s') 91 92 return txt
93 #--------------------------------------------------------
94 - def _get_is_in_use(self):
95 cmd = 'SELECT EXISTS(SELECT 1 FROM bill.bill_item WHERE fk_billable = %(pk)s LIMIT 1)' 96 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': {'pk': self._payload[self._idx['pk_billable']]}}]) 97 return rows[0][0]
98 99 is_in_use = property(_get_is_in_use, lambda x:x)
100 101 #------------------------------------------------------------
102 -def get_billables(active_only=True, order_by=None, return_pks=False):
103 104 if order_by is None: 105 order_by = ' ORDER BY catalog_long, catalog_version, billable_code' 106 else: 107 order_by = ' ORDER BY %s' % order_by 108 109 if active_only: 110 where = 'active IS true' 111 else: 112 where = 'true' 113 114 cmd = (_SQL_get_billable_fields % where) + order_by 115 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd}], get_col_idx = True) 116 if return_pks: 117 return [ r['pk_billable'] for r in rows ] 118 return [ cBillable(row = {'data': r, 'idx': idx, 'pk_field': 'pk_billable'}) for r in rows ]
119 120 #------------------------------------------------------------
121 -def create_billable(code=None, term=None, data_source=None, return_existing=False):
122 args = { 123 'code': code.strip(), 124 'term': term.strip(), 125 'data_src': data_source 126 } 127 cmd = """ 128 INSERT INTO ref.billable (code, term, fk_data_source) 129 SELECT 130 %(code)s, 131 %(term)s, 132 %(data_src)s 133 WHERE NOT EXISTS ( 134 SELECT 1 FROM ref.billable 135 WHERE 136 code = %(code)s 137 AND 138 term = %(term)s 139 AND 140 fk_data_source = %(data_src)s 141 ) 142 RETURNING pk""" 143 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = False, return_data = True) 144 if len(rows) > 0: 145 return cBillable(aPK_obj = rows[0]['pk']) 146 147 if not return_existing: 148 return None 149 150 cmd = """ 151 SELECT * FROM ref.v_billables 152 WHERE 153 code = %(code)s 154 AND 155 term = %(term)s 156 AND 157 pk_data_source = %(data_src)s 158 """ 159 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 160 return cBillable(row = {'data': rows[0], 'idx': idx, 'pk_field': 'pk_billable'})
161 162 #------------------------------------------------------------
163 -def delete_billable(pk_billable=None):
164 cmd = """ 165 DELETE FROM ref.billable 166 WHERE 167 pk = %(pk)s 168 AND 169 NOT EXISTS ( 170 SELECT 1 FROM bill.bill_item WHERE fk_billable = %(pk)s 171 ) 172 """ 173 args = {'pk': pk_billable} 174 gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}])
175 176 #============================================================ 177 # bill items 178 #------------------------------------------------------------ 179 _SQL_get_bill_item_fields = u"SELECT * FROM bill.v_bill_items WHERE %s" 180
181 -class cBillItem(gmBusinessDBObject.cBusinessDBObject):
182 183 _cmd_fetch_payload = _SQL_get_bill_item_fields % u"pk_bill_item = %s" 184 _cmds_store_payload = [ 185 """UPDATE bill.bill_item SET 186 fk_provider = %(pk_provider)s, 187 fk_encounter = %(pk_encounter_to_bill)s, 188 date_to_bill = %(raw_date_to_bill)s, 189 description = gm.nullify_empty_string(%(item_detail)s), 190 net_amount_per_unit = %(net_amount_per_unit)s, 191 currency = gm.nullify_empty_string(%(currency)s), 192 fk_bill = %(pk_bill)s, 193 unit_count = %(unit_count)s, 194 amount_multiplier = %(amount_multiplier)s 195 WHERE 196 pk = %(pk_bill_item)s 197 AND 198 xmin = %(xmin_bill_item)s 199 RETURNING 200 xmin AS xmin_bill_item 201 """] 202 203 _updatable_fields = [ 204 'pk_provider', 205 'pk_encounter_to_bill', 206 'raw_date_to_bill', 207 'item_detail', 208 'net_amount_per_unit', 209 'currency', 210 'pk_bill', 211 'unit_count', 212 'amount_multiplier' 213 ] 214 #--------------------------------------------------------
215 - def format(self):
216 txt = '%s (%s %s%s) [#%s]\n' % ( 217 gmTools.bool2subst( 218 self._payload[self._idx['pk_bill']] is None, 219 _('Open item'), 220 _('Billed item'), 221 ), 222 self._payload[self._idx['catalog_short']], 223 self._payload[self._idx['catalog_version']], 224 gmTools.coalesce(self._payload[self._idx['catalog_language']], '', ' - %s'), 225 self._payload[self._idx['pk_bill_item']] 226 ) 227 txt += ' %s: %s\n' % ( 228 self._payload[self._idx['billable_code']], 229 self._payload[self._idx['billable_description']] 230 ) 231 txt += gmTools.coalesce ( 232 self._payload[self._idx['billable_comment']], 233 '', 234 ' (%s)\n', 235 ) 236 txt += gmTools.coalesce ( 237 self._payload[self._idx['item_detail']], 238 '', 239 _(' Details: %s\n'), 240 ) 241 242 txt += '\n' 243 txt += _(' %s of units: %s\n') % ( 244 gmTools.u_numero, 245 self._payload[self._idx['unit_count']] 246 ) 247 txt += _(' Amount per unit: %(curr)s%(val_p_unit)s (%(cat_curr)s%(cat_val)s per catalog)\n') % { 248 'curr': self._payload[self._idx['currency']], 249 'val_p_unit': self._payload[self._idx['net_amount_per_unit']], 250 'cat_curr': self._payload[self._idx['billable_currency']], 251 'cat_val': self._payload[self._idx['billable_amount']] 252 } 253 txt += _(' Amount multiplier: %s\n') % self._payload[self._idx['amount_multiplier']] 254 txt += _(' VAT would be: %(perc_vat)s%% %(equals)s %(curr)s%(vat)s\n') % { 255 'perc_vat': self._payload[self._idx['vat_multiplier']] * 100, 256 'equals': gmTools.u_corresponds_to, 257 'curr': self._payload[self._idx['currency']], 258 'vat': self._payload[self._idx['vat']] 259 } 260 261 txt += '\n' 262 txt += _(' Charge date: %s') % gmDateTime.pydt_strftime ( 263 self._payload[self._idx['date_to_bill']], 264 '%Y %b %d', 265 accuracy = gmDateTime.acc_days 266 ) 267 bill = self.bill 268 if bill is not None: 269 txt += _('\n On bill: %s') % bill['invoice_id'] 270 271 return txt
272 #--------------------------------------------------------
273 - def _get_billable(self):
274 return cBillable(aPK_obj = self._payload[self._idx['pk_billable']])
275 276 billable = property(_get_billable, lambda x:x) 277 #--------------------------------------------------------
278 - def _get_bill(self):
279 if self._payload[self._idx['pk_bill']] is None: 280 return None 281 return cBill(aPK_obj = self._payload[self._idx['pk_bill']])
282 283 bill = property(_get_bill, lambda x:x) 284 #--------------------------------------------------------
285 - def _get_is_in_use(self):
286 return self._payload[self._idx['pk_bill']] is not None
287 288 is_in_use = property(_get_is_in_use, lambda x:x)
289 #------------------------------------------------------------
290 -def get_bill_items(pk_patient=None, non_invoiced_only=False, return_pks=False):
291 if non_invoiced_only: 292 cmd = _SQL_get_bill_item_fields % u"pk_patient = %(pat)s AND pk_bill IS NULL" 293 else: 294 cmd = _SQL_get_bill_item_fields % u"pk_patient = %(pat)s" 295 args = {'pat': pk_patient} 296 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 297 if return_pks: 298 return [ r['pk_bill_item'] for r in rows ] 299 return [ cBillItem(row = {'data': r, 'idx': idx, 'pk_field': 'pk_bill_item'}) for r in rows ]
300 301 #------------------------------------------------------------
302 -def create_bill_item(pk_encounter=None, pk_billable=None, pk_staff=None):
303 304 billable = cBillable(aPK_obj = pk_billable) 305 cmd = """ 306 INSERT INTO bill.bill_item ( 307 fk_provider, 308 fk_encounter, 309 net_amount_per_unit, 310 currency, 311 fk_billable 312 ) VALUES ( 313 %(staff)s, 314 %(enc)s, 315 %(val)s, 316 %(curr)s, 317 %(billable)s 318 ) 319 RETURNING pk""" 320 args = { 321 'staff': pk_staff, 322 'enc': pk_encounter, 323 'val': billable['raw_amount'], 324 'curr': billable['currency'], 325 'billable': pk_billable 326 } 327 rows, idx = gmPG2.run_rw_queries(queries = [{'cmd': cmd, 'args': args}], return_data = True) 328 return cBillItem(aPK_obj = rows[0][0])
329 330 #------------------------------------------------------------
331 -def delete_bill_item(link_obj=None, pk_bill_item=None):
332 cmd = 'DELETE FROM bill.bill_item WHERE pk = %(pk)s AND fk_bill IS NULL' 333 args = {'pk': pk_bill_item} 334 gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}])
335 336 #============================================================ 337 # bills 338 #------------------------------------------------------------ 339 _SQL_get_bill_fields = """SELECT * FROM bill.v_bills WHERE %s""" 340
341 -class cBill(gmBusinessDBObject.cBusinessDBObject):
342 """Represents a bill""" 343 344 _cmd_fetch_payload = _SQL_get_bill_fields % "pk_bill = %s" 345 _cmds_store_payload = [ 346 """UPDATE bill.bill SET 347 invoice_id = gm.nullify_empty_string(%(invoice_id)s), 348 close_date = %(close_date)s, 349 apply_vat = %(apply_vat)s, 350 comment = gm.nullify_empty_string(%(comment)s), 351 fk_receiver_identity = %(pk_receiver_identity)s, 352 fk_receiver_address = %(pk_receiver_address)s, 353 fk_doc = %(pk_doc)s 354 WHERE 355 pk = %(pk_bill)s 356 AND 357 xmin = %(xmin_bill)s 358 RETURNING 359 pk as pk_bill, 360 xmin as xmin_bill 361 """ 362 ] 363 _updatable_fields = [ 364 'invoice_id', 365 'pk_receiver_identity', 366 'close_date', 367 'apply_vat', 368 'comment', 369 'pk_receiver_address', 370 'pk_doc' 371 ] 372 #--------------------------------------------------------
373 - def format(self, include_receiver=True, include_doc=True):
374 txt = '%s [#%s]\n' % ( 375 gmTools.bool2subst ( 376 (self._payload[self._idx['close_date']] is None), 377 _('Open bill'), 378 _('Closed bill') 379 ), 380 self._payload[self._idx['pk_bill']] 381 ) 382 txt += _(' Invoice ID: %s\n') % self._payload[self._idx['invoice_id']] 383 384 if self._payload[self._idx['close_date']] is not None: 385 txt += _(' Closed: %s\n') % gmDateTime.pydt_strftime ( 386 self._payload[self._idx['close_date']], 387 '%Y %b %d', 388 accuracy = gmDateTime.acc_days 389 ) 390 391 if self._payload[self._idx['comment']] is not None: 392 txt += _(' Comment: %s\n') % self._payload[self._idx['comment']] 393 394 txt += _(' Bill value: %(curr)s%(val)s\n') % { 395 'curr': self._payload[self._idx['currency']], 396 'val': self._payload[self._idx['total_amount']] 397 } 398 399 if self._payload[self._idx['apply_vat']] is None: 400 txt += _(' VAT: undecided\n') 401 elif self._payload[self._idx['apply_vat']] is True: 402 txt += _(' VAT: %(perc_vat)s%% %(equals)s %(curr)s%(vat)s\n') % { 403 'perc_vat': self._payload[self._idx['percent_vat']], 404 'equals': gmTools.u_corresponds_to, 405 'curr': self._payload[self._idx['currency']], 406 'vat': self._payload[self._idx['total_vat']] 407 } 408 txt += _(' Value + VAT: %(curr)s%(val)s\n') % { 409 'curr': self._payload[self._idx['currency']], 410 'val': self._payload[self._idx['total_amount_with_vat']] 411 } 412 else: 413 txt += _(' VAT: does not apply\n') 414 415 if self._payload[self._idx['pk_bill_items']] is None: 416 txt += _(' Items billed: 0\n') 417 else: 418 txt += _(' Items billed: %s\n') % len(self._payload[self._idx['pk_bill_items']]) 419 if include_doc: 420 txt += _(' Invoice: %s\n') % ( 421 gmTools.bool2subst ( 422 self._payload[self._idx['pk_doc']] is None, 423 _('not available'), 424 '#%s' % self._payload[self._idx['pk_doc']] 425 ) 426 ) 427 txt += _(' Patient: #%s\n') % self._payload[self._idx['pk_patient']] 428 if include_receiver: 429 txt += gmTools.coalesce ( 430 self._payload[self._idx['pk_receiver_identity']], 431 '', 432 _(' Receiver: #%s\n') 433 ) 434 if self._payload[self._idx['pk_receiver_address']] is not None: 435 txt += '\n '.join(gmDemographicRecord.get_patient_address(pk_patient_address = self._payload[self._idx['pk_receiver_address']]).format()) 436 437 return txt
438 #--------------------------------------------------------
439 - def add_items(self, items=None):
440 """Requires no pending changes within the bill itself.""" 441 # should check for item consistency first 442 conn = gmPG2.get_connection(readonly = False) 443 for item in items: 444 item['pk_bill'] = self._payload[self._idx['pk_bill']] 445 item.save(conn = conn) 446 conn.commit() 447 self.refetch_payload() # make sure aggregates are re-filled from view
448 #--------------------------------------------------------
449 - def _get_bill_items(self):
450 return [ cBillItem(aPK_obj = pk) for pk in self._payload[self._idx['pk_bill_items']] ]
451 452 bill_items = property(_get_bill_items, lambda x:x) 453 #--------------------------------------------------------
454 - def _get_invoice(self):
455 if self._payload[self._idx['pk_doc']] is None: 456 return None 457 return gmDocuments.cDocument(aPK_obj = self._payload[self._idx['pk_doc']])
458 459 invoice = property(_get_invoice, lambda x:x) 460 #--------------------------------------------------------
461 - def _get_address(self):
462 if self._payload[self._idx['pk_receiver_address']] is None: 463 return None 464 return gmDemographicRecord.get_address_from_patient_address_pk ( 465 pk_patient_address = self._payload[self._idx['pk_receiver_address']] 466 )
467 468 address = property(_get_address, lambda x:x) 469 #--------------------------------------------------------
470 - def _get_default_address(self):
471 return gmDemographicRecord.get_patient_address_by_type ( 472 pk_patient = self._payload[self._idx['pk_patient']], 473 adr_type = 'billing' 474 )
475 476 default_address = property(_get_default_address, lambda x:x) 477 #--------------------------------------------------------
478 - def _get_home_address(self):
479 return gmDemographicRecord.get_patient_address_by_type ( 480 pk_patient = self._payload[self._idx['pk_patient']], 481 adr_type = 'home' 482 )
483 484 home_address = property(_get_home_address, lambda x:x) 485 #--------------------------------------------------------
487 if self._payload[self._idx['pk_receiver_address']] is not None: 488 return True 489 adr = self.default_address 490 if adr is None: 491 adr = self.home_address 492 if adr is None: 493 return False 494 self['pk_receiver_address'] = adr['pk_lnk_person_org_address'] 495 return self.save_payload()
496 497 #------------------------------------------------------------
498 -def get_bills(order_by=None, pk_patient=None, return_pks=False):
499 500 args = {'pat': pk_patient} 501 where_parts = ['true'] 502 503 if pk_patient is not None: 504 where_parts.append('pk_patient = %(pat)s') 505 506 if order_by is None: 507 order_by = '' 508 else: 509 order_by = ' ORDER BY %s' % order_by 510 511 cmd = (_SQL_get_bill_fields % ' AND '.join(where_parts)) + order_by 512 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 513 if return_pks: 514 return [ r['pk_bill'] for r in rows ] 515 return [ cBill(row = {'data': r, 'idx': idx, 'pk_field': 'pk_bill'}) for r in rows ]
516 517 #------------------------------------------------------------
518 -def get_bills4document(pk_document=None):
519 args = {'pk_doc': pk_document} 520 cmd = _SQL_get_bill_fields % 'pk_doc = %(pk_doc)s' 521 rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': args}], get_col_idx = True) 522 return [ cBill(row = {'data': r, 'idx': idx, 'pk_field': 'pk_bill'}) for r in rows ]
523 524 #------------------------------------------------------------
525 -def create_bill(conn=None, invoice_id=None):
526 527 args = {'inv_id': invoice_id} 528 cmd = """ 529 INSERT INTO bill.bill (invoice_id) 530 VALUES (gm.nullify_empty_string(%(inv_id)s)) 531 RETURNING pk 532 """ 533 rows, idx = gmPG2.run_rw_queries(link_obj = conn, queries = [{'cmd': cmd, 'args': args}], return_data = True, get_col_idx = False) 534 535 return cBill(aPK_obj = rows[0]['pk'])
536 537 #------------------------------------------------------------
538 -def delete_bill(link_obj=None, pk_bill=None):
539 args = {'pk': pk_bill} 540 cmd = "DELETE FROM bill.bill WHERE pk = %(pk)s" 541 gmPG2.run_rw_queries(link_obj = link_obj, queries = [{'cmd': cmd, 'args': args}]) 542 return True
543 544 #------------------------------------------------------------
545 -def get_bill_receiver(pk_patient=None):
546 pass
547 548 #------------------------------------------------------------
549 -def get_invoice_id(pk_patient=None):
550 return 'GM%s / %s' % ( 551 pk_patient, 552 gmDateTime.pydt_strftime ( 553 gmDateTime.pydt_now_here(), 554 '%Y-%m-%d / %H%M%S' 555 ) 556 )
557 558 #------------------------------------------------------------
559 -def get_scan2pay_data(branch, bill, provider=None, comment=None):
560 """Create scan2pay data for generating a QR code. 561 562 https://www.scan2pay.info 563 -------------------------------- 564 BCD # (3) fixed, barcode tag 565 002 # (3) fixed, version 566 1 # (1) charset, 1 = utf8 567 SCT # (3) fixed 568 $<praxis_id::BIC//Bank//%(value)s::11>$ # (11) <BIC> 569 $2<range_of::$<current_provider_name::%(lastnames)s::>$,$<praxis::%(praxis)s::>$::70>2$ # (70) <Name of beneficiary> "Empfänger" - Praxis 570 $<praxis_id::IBAN//Bank//%(value)s::34>$ # (34) <IBAN> 571 EUR$<bill::%(total_amount_with_vat)s::12>$ # (12) <Amount in EURO> "EUR12.5" 572 # (4) <purpose of transfer> - leer 573 # (35) <remittance info - struct> - only this XOR the next field - GNUmed: leer 574 $2<range_of::InvID=$<bill::%(invoice_id)s::>$/Date=$<today::%d.%B %Y::>$::140$>2$ # (140) <remittance info - text> "Client:Marie Louise La Lune" - "Rg Nr, date" 575 <beneficiary-to-payor info> # (70) "pay soon :-)" - optional - GNUmed nur wenn bytes verfügbar 576 -------------------------------- 577 total: 331 bytes (not chars ! - cave UTF8) 578 EOL: LF or CRLF 579 last *used* element not followed by anything, IOW can omit pending non-used elements 580 """ 581 assert (branch is not None), '<branch> must not be <None>' 582 assert (bill is not None), '<bill> must not be <None>' 583 584 data = {} 585 IBANs = branch.get_external_ids(id_type = 'IBAN', issuer = 'Bank') 586 if len(IBANs) == 0: 587 _log.debug('no IBAN found, cannot create scan2pay data') 588 return None 589 data['IBAN'] = IBANs[0]['value'][:34] 590 data['beneficiary'] = gmTools.coalesce ( 591 value2test = provider, 592 return_instead = branch['praxis'][:70], 593 template4value = '%%(lastnames)s, %s' % branch['praxis'] 594 )[:70] 595 BICs = branch.get_external_ids(id_type = 'BIC', issuer = 'Bank') 596 if len(BICs) == 0: 597 data['BIC'] = '' 598 else: 599 data['BIC'] = BICs[0]['value'][:11] 600 data['amount'] = bill['total_amount_with_vat'][:9] 601 data['ref'] = (_('Inv: %s, %s') % ( 602 bill['invoice_id'], 603 gmDateTime.pydt_strftime(gmDateTime.pydt_now_here(), '%d.%B %Y') 604 ))[:140] 605 data['cmt'] = gmTools.coalesce(comment, '', '\n%s')[:70] 606 607 data_str = 'BCD\n002\n1\nSCT\n%(BIC)s\n%(beneficiary)s\n%(IBAN)s\nEUR%(amount)s\n\n\n%(ref)s%(cmt)s' % data 608 data_str_bytes = bytes(data_str, 'utf8')[:331] 609 return str(data_str_bytes, 'utf8')
610 611 #============================================================ 612 # main 613 #------------------------------------------------------------ 614 if __name__ == "__main__": 615 616 if len(sys.argv) < 2: 617 sys.exit() 618 619 if sys.argv[1] != 'test': 620 sys.exit() 621 622 # from Gnumed.pycommon import gmLog2 623 # from Gnumed.pycommon import gmI18N 624 # from Gnumed.business import gmPerson 625 from Gnumed.business import gmPraxis 626 627 # gmI18N.activate_locale() 628 ## gmDateTime.init() 629
630 - def test_default_address():
631 bills = get_bills(pk_patient = 12) 632 first_bill = bills[0] 633 print(first_bill.default_address)
634
635 - def test_me():
636 print("--------------") 637 me = cBillable(aPK_obj=1) 638 fields = me.get_fields() 639 for field in fields: 640 print(field, ':', me[field]) 641 print("updatable:", me.get_updatable_fields())
642 #me['vat']=4; me.store_payload() 643 644 #--------------------------------------------------
645 - def test_get_scan2pay_data():
646 prax = gmPraxis.get_praxis_branches()[0] 647 bills = get_bills(pk_patient = 12) 648 print(get_scan2pay_data ( 649 prax, 650 bills[0], 651 provider=None, 652 comment = 'GNUmed test harness' + ('x' * 400) 653 ))
654 655 #-------------------------------------------------- 656 #test_me() 657 #test_default_address() 658 test_get_scan2pay_data() 659