Package Gnumed :: Package wxpython :: Module gmBillingWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmBillingWidgets

   1  """GNUmed billing handling widgets. 
   2  """ 
   3  #================================================================ 
   4  __author__ = "Karsten Hilbert <Karsten.Hilbert@gmx.net>" 
   5  __license__ = "GPL v2 or later" 
   6   
   7  import logging 
   8  import sys 
   9   
  10   
  11  import wx 
  12   
  13   
  14  if __name__ == '__main__': 
  15          sys.path.insert(0, '../../') 
  16  from Gnumed.pycommon import gmTools 
  17  from Gnumed.pycommon import gmDateTime 
  18  from Gnumed.pycommon import gmMatchProvider 
  19  from Gnumed.pycommon import gmDispatcher 
  20  from Gnumed.pycommon import gmPG2 
  21  from Gnumed.pycommon import gmCfg 
  22  from Gnumed.pycommon import gmPrinting 
  23  from Gnumed.pycommon import gmNetworkTools 
  24   
  25  from Gnumed.business import gmBilling 
  26  from Gnumed.business import gmPerson 
  27  from Gnumed.business import gmStaff 
  28  from Gnumed.business import gmDocuments 
  29  from Gnumed.business import gmSurgery 
  30  from Gnumed.business import gmForms 
  31  from Gnumed.business import gmDemographicRecord 
  32   
  33  from Gnumed.wxpython import gmListWidgets 
  34  from Gnumed.wxpython import gmRegetMixin 
  35  from Gnumed.wxpython import gmPhraseWheel 
  36  from Gnumed.wxpython import gmGuiHelpers 
  37  from Gnumed.wxpython import gmEditArea 
  38  from Gnumed.wxpython import gmPersonContactWidgets 
  39  from Gnumed.wxpython import gmMacro 
  40  from Gnumed.wxpython import gmFormWidgets 
  41  from Gnumed.wxpython import gmDocumentWidgets 
  42  from Gnumed.wxpython import gmDataPackWidgets 
  43   
  44   
  45  _log = logging.getLogger('gm.ui') 
  46   
  47  #================================================================ 
48 -def manage_billables(parent=None):
49 50 if parent is None: 51 parent = wx.GetApp().GetTopWindow() 52 #------------------------------------------------------------ 53 # def edit(substance=None): 54 # return edit_consumable_substance(parent = parent, substance = substance, single_entry = (substance is not None)) 55 #------------------------------------------------------------ 56 def delete(billable): 57 if billable.is_in_use: 58 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete this billable item. It is in use.'), beep = True) 59 return False 60 return gmBilling.delete_billable(pk_billable = billable['pk_billable'])
61 #------------------------------------------------------------ 62 def get_tooltip(item): 63 if item is None: 64 return None 65 return item.format() 66 #------------------------------------------------------------ 67 def refresh(lctrl): 68 billables = gmBilling.get_billables() 69 items = [ [ 70 b['billable_code'], 71 b['billable_description'], 72 u'%s %s' % (b['raw_amount'], b['currency']), 73 u'%s (%s)' % (b['catalog_short'], b['catalog_version']), 74 gmTools.coalesce(b['comment'], u''), 75 b['pk_billable'] 76 ] for b in billables ] 77 lctrl.set_string_items(items) 78 lctrl.set_data(billables) 79 #------------------------------------------------------------ 80 def manage_data_packs(billable): 81 gmDataPackWidgets.manage_data_packs(parent = parent) 82 return True 83 #------------------------------------------------------------ 84 def browse_catalogs(billable): 85 dbcfg = gmCfg.cCfgSQL() 86 url = dbcfg.get2 ( 87 option = 'external.urls.schedules_of_fees', 88 workplace = gmSurgery.gmCurrentPractice().active_workplace, 89 bias = 'user', 90 default = u'http://www.e-bis.de/goae/defaultFrame.htm' 91 ) 92 gmNetworkTools.open_url_in_browser(url = url) 93 return False 94 #------------------------------------------------------------ 95 msg = _('\nThese are the items for billing registered with GNUmed.\n') 96 97 gmListWidgets.get_choices_from_list ( 98 parent = parent, 99 msg = msg, 100 caption = _('Showing billable items.'), 101 columns = [_('Code'), _('Description'), _('Value'), _('Catalog'), _('Comment'), u'#'], 102 single_selection = True, 103 #new_callback = edit, 104 #edit_callback = edit, 105 delete_callback = delete, 106 refresh_callback = refresh, 107 middle_extra_button = ( 108 _('Data packs'), 109 _('Browse and install billing catalog (schedule of fees) data packs'), 110 manage_data_packs 111 ), 112 right_extra_button = ( 113 _('Catalogs (WWW)'), 114 _('Browse billing catalogs (schedules of fees) on the web'), 115 browse_catalogs 116 ), 117 list_tooltip_callback = get_tooltip 118 ) 119 120 #================================================================
121 -class cBillablePhraseWheel(gmPhraseWheel.cPhraseWheel):
122
123 - def __init__(self, *args, **kwargs):
124 gmPhraseWheel.cPhraseWheel.__init__(self, *args, **kwargs) 125 query = u""" 126 SELECT -- DISTINCT ON (label) 127 r_vb.pk_billable 128 AS data, 129 r_vb.billable_code || ': ' || r_vb.billable_description || ' (' || r_vb.catalog_short || ' - ' || r_vb.catalog_version || ')' 130 AS list_label, 131 r_vb.billable_code || ' (' || r_vb.catalog_short || ' - ' || r_vb.catalog_version || ')' 132 AS field_label 133 FROM 134 ref.v_billables r_vb 135 WHERE 136 r_vb.active 137 AND ( 138 r_vb.billable_code %(fragment_condition)s 139 OR 140 r_vb.billable_description %(fragment_condition)s 141 ) 142 ORDER BY list_label 143 LIMIT 20 144 """ 145 mp = gmMatchProvider.cMatchProvider_SQL2(queries = query) 146 mp.setThresholds(1, 2, 4) 147 self.matcher = mp
148 #------------------------------------------------------------
149 - def _data2instance(self):
150 return gmBilling.cBillable(aPK_obj = self._data.values()[0]['data'])
151 #------------------------------------------------------------
152 - def _get_data_tooltip(self):
153 if self.GetData() is None: 154 return None 155 billable = gmBilling.cBillable(aPK_obj = self._data.values()[0]['data']) 156 return billable.format()
157 #------------------------------------------------------------
158 - def set_from_instance(self, instance):
159 val = u'%s (%s - %s)' % ( 160 instance['billable_code'], 161 instance['catalog_short'], 162 instance['catalog_version'] 163 ) 164 self.SetText(value = val, data = instance['pk_billable'])
165 #------------------------------------------------------------
166 - def set_from_pk(self, pk):
167 self.set_from_instance(gmBilling.cBillable(aPK_obj = pk))
168 169 #================================================================ 170 # invoice related widgets 171 #----------------------------------------------------------------
172 -def configure_invoice_template(parent=None, with_vat=True):
173 174 if parent is None: 175 parent = wx.GetApp().GetTopWindow() 176 177 template = gmFormWidgets.manage_form_templates ( 178 parent = parent, 179 template_types = ['invoice'] 180 ) 181 182 if template is None: 183 gmDispatcher.send(signal = 'statustext', msg = _('No invoice template configured.'), beep = True) 184 return None 185 186 if template['engine'] != u'L': 187 gmDispatcher.send(signal = 'statustext', msg = _('No invoice template configured.'), beep = True) 188 return None 189 190 if with_vat: 191 option = u'form_templates.invoice_with_vat' 192 else: 193 option = u'form_templates.invoice_no_vat' 194 195 dbcfg = gmCfg.cCfgSQL() 196 dbcfg.set ( 197 workplace = gmSurgery.gmCurrentPractice().active_workplace, 198 option = option, 199 value = u'%s - %s' % (template['name_long'], template['external_version']) 200 ) 201 202 return template
203 #----------------------------------------------------------------
204 -def get_invoice_template(parent=None, with_vat=True):
205 206 dbcfg = gmCfg.cCfgSQL() 207 if with_vat: 208 option = u'form_templates.invoice_with_vat' 209 else: 210 option = u'form_templates.invoice_no_vat' 211 212 template = dbcfg.get2 ( 213 option = option, 214 workplace = gmSurgery.gmCurrentPractice().active_workplace, 215 bias = 'user' 216 ) 217 218 if template is None: 219 template = configure_invoice_template(parent = parent, with_vat = with_vat) 220 if template is None: 221 gmGuiHelpers.gm_show_error ( 222 aMessage = _('There is no invoice template configured.'), 223 aTitle = _('Getting invoice template') 224 ) 225 return None 226 else: 227 try: 228 name, ver = template.split(u' - ') 229 except: 230 _log.exception('problem splitting invoice template name [%s]', template) 231 gmDispatcher.send(signal = 'statustext', msg = _('Problem loading invoice template.'), beep = True) 232 return None 233 template = gmForms.get_form_template(name_long = name, external_version = ver) 234 if template is None: 235 gmGuiHelpers.gm_show_error ( 236 aMessage = _('Cannot load invoice template [%s - %s]') % (name, ver), 237 aTitle = _('Getting invoice template') 238 ) 239 return None 240 241 return template
242 243 #================================================================ 244 # per-patient bill related widgets 245 #----------------------------------------------------------------
246 -def edit_bill(parent=None, bill=None, single_entry=False):
247 248 if bill is None: 249 # manually creating bills is not yet supported 250 return 251 252 ea = cBillEAPnl(parent = parent, id = -1) 253 ea.data = bill 254 ea.mode = gmTools.coalesce(bill, 'new', 'edit') 255 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 256 dlg.SetTitle(gmTools.coalesce(bill, _('Adding new bill'), _('Editing bill'))) 257 if dlg.ShowModal() == wx.ID_OK: 258 dlg.Destroy() 259 return True 260 dlg.Destroy() 261 return False
262 #----------------------------------------------------------------
263 -def create_bill_from_items(bill_items=None):
264 265 if len(bill_items) == 0: 266 return None 267 268 item = bill_items[0] 269 currency = item['currency'] 270 vat = item['vat_multiplier'] 271 pat = item['pk_patient'] 272 273 # check item consistency 274 has_errors = False 275 for item in bill_items: 276 if (item['currency'] != currency) or ( 277 item['vat_multiplier'] != vat) or ( 278 item['pk_patient'] != pat 279 ): 280 msg = _( 281 'All items to be included with a bill must\n' 282 'coincide on currency, VAT, and patient.\n' 283 '\n' 284 'This item does not:\n' 285 '\n' 286 '%s\n' 287 ) % item.format() 288 has_errors = True 289 290 if item['pk_bill'] is not None: 291 msg = _( 292 'This item is already invoiced:\n' 293 '\n' 294 '%s\n' 295 '\n' 296 'Cannot put it on a second bill.' 297 ) % item.format() 298 has_errors = True 299 300 if has_errors: 301 gmGuiHelpers.gm_show_warning(aTitle = _('Checking invoice items'), aMessage = msg) 302 return None 303 304 # create bill 305 bill = gmBilling.create_bill(invoice_id = gmBilling.get_invoice_id(pk_patient = pat)) 306 _log.info('created bill [%s]', bill['invoice_id']) 307 bill.add_items(items = bill_items) 308 bill.set_missing_address_from_default() 309 310 return bill
311 #----------------------------------------------------------------
312 -def create_invoice_from_bill(parent = None, bill=None, print_it=False, keep_a_copy=True):
313 314 if None in [ bill['close_date'], bill['pk_receiver_address'] ]: 315 edit_bill(parent = parent, bill = bill, single_entry = True) 316 # cannot invoice open bills 317 if bill['close_date'] is None: 318 _log.error('cannot create invoice from bill, bill not closed') 319 gmGuiHelpers.gm_show_warning ( 320 aTitle = _('Creating invoice'), 321 aMessage = _( 322 'Cannot create invoice from bill.\n' 323 '\n' 324 'The bill is not closed.' 325 ) 326 ) 327 return False 328 # cannot create invoice if no receiver address 329 if bill['pk_receiver_address'] is None: 330 _log.error('cannot create invoice from bill, lacking receiver address') 331 gmGuiHelpers.gm_show_warning ( 332 aTitle = _('Creating invoice'), 333 aMessage = _( 334 'Cannot create invoice from bill.\n' 335 '\n' 336 'There is no receiver address.' 337 ) 338 ) 339 return False 340 341 # find template 342 template = get_invoice_template(parent = parent, with_vat = bill['apply_vat']) 343 if template is None: 344 gmGuiHelpers.gm_show_warning ( 345 aTitle = _('Creating invoice'), 346 aMessage = _( 347 'Cannot create invoice from bill\n' 348 'without an invoice template.' 349 ) 350 ) 351 return False 352 353 # process template 354 try: 355 invoice = template.instantiate() 356 except KeyError: 357 _log.exception('cannot instantiate invoice template [%s]', template) 358 gmGuiHelpers.gm_show_error ( 359 aMessage = _('Invalid invoice template [%s - %s (%s)]') % (name, ver, template['engine']), 360 aTitle = _('Printing medication list') 361 ) 362 return False 363 364 ph = gmMacro.gmPlaceholderHandler() 365 #ph.debug = True 366 ph.set_cache_value('bill', bill) 367 invoice.substitute_placeholders(data_source = ph) 368 ph.unset_cache_value('bill') 369 pdf_name = invoice.generate_output() 370 if pdf_name is None: 371 gmGuiHelpers.gm_show_error ( 372 aMessage = _('Error generating invoice PDF.'), 373 aTitle = _('Creating invoice') 374 ) 375 return False 376 377 # keep a copy 378 if keep_a_copy: 379 files2import = [] 380 files2import.extend(invoice.final_output_filenames) 381 files2import.extend(invoice.re_editable_filenames) 382 doc = gmDocumentWidgets.save_files_as_new_document ( 383 parent = parent, 384 filenames = files2import, 385 document_type = template['instance_type'], 386 review_as_normal = True, 387 reference = bill['invoice_id'] 388 ) 389 bill['pk_doc'] = doc['pk_doc'] 390 bill.save() 391 392 if not print_it: 393 return True 394 395 # print template 396 printed = gmPrinting.print_files(filenames = [pdf_name], jobtype = 'invoice') 397 if not printed: 398 gmGuiHelpers.gm_show_error ( 399 aMessage = _('Error printing the invoice.'), 400 aTitle = _('Printing invoice') 401 ) 402 return True 403 404 return True
405 406 #----------------------------------------------------------------
407 -def delete_bill(parent=None, bill=None):
408 409 if parent is None: 410 parent = wx.GetApp().GetTopWindow() 411 412 dlg = gmGuiHelpers.c3ButtonQuestionDlg ( 413 parent, -1, 414 caption = _('Deleting bill'), 415 question = _( 416 'When deleting the bill [%s]\n' 417 'do you want to keep its items (effectively \"unbilling\" them)\n' 418 'or do you want to also delete the bill items from the patient ?\n' 419 ) % bill['invoice_id'], 420 button_defs = [ 421 {'label': _('Delete + keep'), 'tooltip': _('Delete the bill but keep ("unbill") its items.'), 'default': True}, 422 {'label': _('Delete all'), 'tooltip': _('Delete both the bill and its items from the patient.')} 423 ], 424 show_checkbox = True, 425 checkbox_msg = _('Also remove invoice PDF'), 426 checkbox_tooltip = _('Also remove the invoice PDF from the document archive (because it will not correspond to the bill anymore).') 427 ) 428 button_pressed = dlg.ShowModal() 429 delete_invoice = dlg.checkbox_is_checked() 430 dlg.Destroy() 431 432 if button_pressed == wx.ID_CANCEL: 433 return False 434 435 if button_pressed == wx.ID_YES: 436 for item in bill.bill_items: 437 item['pk_bill'] = None 438 item.save() 439 440 if button_pressed == wx.ID_NO: 441 for item in bill.bill_items: 442 item['pk_bill'] = None 443 item.save() 444 gmBilling.delete_bill_item(pk_bill_item = item['pk_bill_item']) 445 446 if delete_invoice: 447 if bill['pk_doc'] is not None: 448 gmDocuments.delete_document ( 449 document_id = bill['pk_doc'], 450 encounter_id = gmPerson.cPatient(aPK_obj = bill['pk_patient']).emr.active_encounter['pk_encounter'] 451 ) 452 453 return gmBilling.delete_bill(pk_bill = bill['pk_bill'])
454 455 #----------------------------------------------------------------
456 -def remove_items_from_bill(parent=None, bill=None):
457 458 if bill is None: 459 return False 460 461 list_data = bill.bill_items 462 if len(list_data) == 0: 463 return False 464 465 if parent is None: 466 parent = wx.GetApp().GetTopWindow() 467 468 list_items = [ [ 469 gmDateTime.pydt_strftime(b['date_to_bill'], '%x', accuracy = gmDateTime.acc_days), 470 b['unit_count'], 471 u'%s: %s%s' % (b['billable_code'], b['billable_description'], gmTools.coalesce(b['item_detail'], u'', u' - %s')), 472 u'%s %s (%s %s %s%s%s)' % ( 473 b['total_amount'], 474 b['currency'], 475 b['unit_count'], 476 gmTools.u_multiply, 477 b['net_amount_per_unit'], 478 gmTools.u_multiply, 479 b['amount_multiplier'] 480 ), 481 u'%s %s (%s%%)' % ( 482 b['vat'], 483 b['currency'], 484 b['vat_multiplier'] * 100 485 ), 486 u'%s (%s)' % (b['catalog_short'], b['catalog_version']), 487 b['pk_bill_item'] 488 ] for b in list_data ] 489 490 msg = _('Select the items you want to remove from bill [%s]:\n') % bill['invoice_id'] 491 items2remove = gmListWidgets.get_choices_from_list ( 492 parent = parent, 493 msg = msg, 494 caption = _('Removing items from bill'), 495 columns = [_('Date'), _('Count'), _('Description'), _('Value'), _('VAT'), _('Catalog'), u'#'], 496 single_selection = False, 497 choices = list_items, 498 data = list_data 499 ) 500 501 if items2remove is None: 502 return False 503 504 dlg = gmGuiHelpers.c3ButtonQuestionDlg ( 505 parent, -1, 506 caption = _('Removing items from bill'), 507 question = _( 508 '%s items selected from bill [%s]\n' 509 '\n' 510 'Do you want to only remove the selected items\n' 511 'from the bill ("unbill" them) or do you want\n' 512 'to delete them entirely from the patient ?\n' 513 '\n' 514 'Note that neither action is reversible.' 515 ) % ( 516 len(items2remove), 517 bill['invoice_id'] 518 ), 519 button_defs = [ 520 {'label': _('"Unbill"'), 'tooltip': _('Only "unbill" items (remove from bill but do not delete from patient).'), 'default': True}, 521 {'label': _('Delete'), 'tooltip': _('Completely delete items from the patient.')} 522 ], 523 show_checkbox = True, 524 checkbox_msg = _('Also remove invoice PDF'), 525 checkbox_tooltip = _('Also remove the invoice PDF from the document archive (because it will not correspond to the bill anymore).') 526 ) 527 button_pressed = dlg.ShowModal() 528 delete_invoice = dlg.checkbox_is_checked() 529 dlg.Destroy() 530 531 if button_pressed == wx.ID_CANCEL: 532 return False 533 534 # remember this because unlinking/deleting the items 535 # will remove the patient PK from the bill 536 pk_patient = bill['pk_patient'] 537 538 for item in items2remove: 539 item['pk_bill'] = None 540 item.save() 541 if button_pressed == wx.ID_NO: 542 gmBilling.delete_bill_item(pk_bill_item = item['pk_bill_item']) 543 544 if delete_invoice: 545 if bill['pk_doc'] is not None: 546 gmDocuments.delete_document ( 547 document_id = bill['pk_doc'], 548 encounter_id = gmPerson.cPatient(aPK_obj = pk_patient).emr.active_encounter['pk_encounter'] 549 ) 550 551 # delete bill, too, if empty 552 if len(bill.bill_items) == 0: 553 gmBilling.delete_bill(pk_bill = bill['pk_bill']) 554 555 return True
556 #----------------------------------------------------------------
557 -def manage_bills(parent=None, patient=None):
558 559 if parent is None: 560 parent = wx.GetApp().GetTopWindow() 561 562 #------------------------------------------------------------ 563 def show_pdf(bill): 564 if bill is None: 565 return False 566 567 # find invoice 568 invoice = bill.invoice 569 if invoice is not None: 570 success, msg = invoice.parts[-1].display_via_mime() 571 if not success: 572 gmGuiHelpers.gm_show_error(aMessage = msg, aTitle = _('Displaying invoice')) 573 return False 574 575 # create it ? 576 create_it = gmGuiHelpers.gm_show_question ( 577 title = _('Displaying invoice'), 578 question = _( 579 'Cannot find an existing\n' 580 'invoice PDF for this bill.\n' 581 '\n' 582 'Do you want to create one ?' 583 ), 584 ) 585 if not create_it: 586 return False 587 588 # prepare invoicing 589 if not bill.set_missing_address_from_default(): 590 gmGuiHelpers.gm_show_warning ( 591 aTitle = _('Creating invoice'), 592 aMessage = _( 593 'There is no pre-configured billing address.\n' 594 '\n' 595 'Select the address you want to send the bill to.' 596 ) 597 ) 598 edit_bill(parent = parent, bill = bill, single_entry = True) 599 if bill['pk_receiver_address'] is None: 600 return False 601 if bill['close_date'] is None: 602 bill['close_date'] = gmDateTime.pydt_now_here() 603 bill.save() 604 605 return create_invoice_from_bill(parent = parent, bill = bill, print_it = True, keep_a_copy = True)
606 #------------------------------------------------------------ 607 def edit(bill): 608 return edit_bill(parent = parent, bill = bill, single_entry = True) 609 #------------------------------------------------------------ 610 def delete(bill): 611 return delete_bill(parent = parent, bill = bill) 612 #------------------------------------------------------------ 613 def remove_items(bill): 614 return remove_items_from_bill(parent = parent, bill = bill) 615 #------------------------------------------------------------ 616 def get_tooltip(item): 617 if item is None: 618 return None 619 return item.format() 620 #------------------------------------------------------------ 621 def refresh(lctrl): 622 if patient is None: 623 bills = gmBilling.get_bills() 624 else: 625 bills = gmBilling.get_bills(pk_patient = patient.ID) 626 items = [] 627 for b in bills: 628 if b['close_date'] is None: 629 close_date = _('<open>') 630 else: 631 close_date = gmDateTime.pydt_strftime(b['close_date'], '%Y %b %d') 632 items.append([ 633 close_date, 634 b['invoice_id'], 635 gmTools.bool2subst ( 636 b['apply_vat'], 637 _('%s %s (with %s%% VAT)') % (b['total_amount_with_vat'], b['currency'], b['percent_vat']), 638 u'%s %s' % (b['total_amount'], b['currency']) 639 ) 640 ]) 641 lctrl.set_string_items(items) 642 lctrl.set_data(bills) 643 #------------------------------------------------------------ 644 return gmListWidgets.get_choices_from_list ( 645 parent = parent, 646 caption = _('Showing bills.'), 647 columns = [_('Close date'), _('Invoice ID'), _('Value')], 648 single_selection = True, 649 edit_callback = edit, 650 delete_callback = delete, 651 refresh_callback = refresh, 652 middle_extra_button = ( 653 u'PDF', 654 _('Create if necessary, and show the corresponding invoice PDF'), 655 show_pdf 656 ), 657 right_extra_button = ( 658 _('Unbill'), 659 _('Select and remove items from a bill.'), 660 remove_items 661 ), 662 list_tooltip_callback = get_tooltip 663 ) 664 665 #---------------------------------------------------------------- 666 from Gnumed.wxGladeWidgets import wxgBillEAPnl 667
668 -class cBillEAPnl(wxgBillEAPnl.wxgBillEAPnl, gmEditArea.cGenericEditAreaMixin):
669
670 - def __init__(self, *args, **kwargs):
671 672 try: 673 data = kwargs['bill'] 674 del kwargs['bill'] 675 except KeyError: 676 data = None 677 678 wxgBillEAPnl.wxgBillEAPnl.__init__(self, *args, **kwargs) 679 gmEditArea.cGenericEditAreaMixin.__init__(self) 680 681 self.mode = 'new' 682 self.data = data 683 if data is not None: 684 self.mode = 'edit'
685 686 # self.__init_ui() 687 #---------------------------------------------------------------- 688 # def __init_ui(self): 689 #---------------------------------------------------------------- 690 # generic Edit Area mixin API 691 #----------------------------------------------------------------
692 - def _valid_for_save(self):
693 validity = True 694 695 # flag but do not count as wrong 696 if not self._PRW_close_date.is_valid_timestamp(allow_empty = False): 697 self._PRW_close_date.SetFocus() 698 699 return validity
700 #----------------------------------------------------------------
701 - def _save_as_new(self):
702 # not intended to be used 703 return False
704 #----------------------------------------------------------------
705 - def _save_as_update(self):
706 self.data['close_date'] = self._PRW_close_date.GetData() 707 self.data['apply_vat'] = self._CHBOX_vat_applies.GetValue() 708 self.data.save() 709 return True
710 #----------------------------------------------------------------
711 - def _refresh_as_new(self):
712 pass # not used
713 #----------------------------------------------------------------
715 self._refresh_as_new()
716 #----------------------------------------------------------------
717 - def _refresh_from_existing(self):
718 self._TCTRL_invoice_id.SetValue(self.data['invoice_id']) 719 self._PRW_close_date.SetText(data = self.data['close_date']) 720 721 self.data.set_missing_address_from_default() 722 if self.data['pk_receiver_address'] is None: 723 self._TCTRL_address.SetValue(u'') 724 else: 725 adr = self.data.address 726 self._TCTRL_address.SetValue(adr.format(single_line = True, show_type = False)) 727 728 self._TCTRL_value.SetValue(u'%s %s' % ( 729 self.data['total_amount'], 730 self.data['currency'] 731 )) 732 self._CHBOX_vat_applies.SetValue(self.data['apply_vat']) 733 self._CHBOX_vat_applies.SetLabel(_('&VAT applies (%s%%)') % self.data['percent_vat']) 734 if self.data['apply_vat']: 735 self._TCTRL_value_with_vat.SetValue(u'%s %s %s %s %s %s %s' % ( 736 gmTools.u_corresponds_to, 737 self.data['total_vat'], 738 self.data['currency'], 739 gmTools.u_right_arrow, 740 gmTools.u_sum, 741 self.data['total_amount_with_vat'], 742 self.data['currency'] 743 )) 744 else: 745 self._TCTRL_value_with_vat.SetValue(u'') 746 747 self._PRW_close_date.SetFocus()
748 #---------------------------------------------------------------- 749 # event handling 750 #----------------------------------------------------------------
751 - def _on_vat_applies_box_checked(self, event):
752 if self._CHBOX_vat_applies.GetValue(): 753 self._TCTRL_value_with_vat.SetValue(u'%s %s %s %s %s %s %s' % ( 754 gmTools.u_corresponds_to, 755 self.data['total_vat'], 756 self.data['currency'], 757 gmTools.u_right_arrow, 758 gmTools.u_sum, 759 self.data['total_amount_with_vat'], 760 self.data['currency'] 761 )) 762 return 763 self._TCTRL_value_with_vat.SetValue(u'')
764 #----------------------------------------------------------------
765 - def _on_select_address_button_pressed(self, event):
766 adr = gmPersonContactWidgets.select_address ( 767 missing = _('billing'), 768 person = gmPerson.cIdentity(aPK_obj = self.data['pk_patient']) 769 ) 770 if adr is None: 771 gmGuiHelpers.gm_show_info ( 772 aTitle = _('Selecting address'), 773 aMessage = _('GNUmed does not know any addresses for this patient.') 774 ) 775 return 776 self.data['pk_receiver_address'] = adr['pk_lnk_person_org_address'] 777 self.data.save() 778 self._TCTRL_address.SetValue(adr.format(single_line = True, show_type = False))
779 780 #================================================================ 781 # per-patient bill items related widgets 782 #----------------------------------------------------------------
783 -def edit_bill_item(parent=None, bill_item=None, single_entry=False):
784 785 if bill_item is not None: 786 if bill_item.is_in_use: 787 gmDispatcher.send(signal = 'statustext', msg = _('Cannot edit already invoiced bill item.'), beep = True) 788 return False 789 790 ea = cBillItemEAPnl(parent = parent, id = -1) 791 ea.data = bill_item 792 ea.mode = gmTools.coalesce(bill_item, 'new', 'edit') 793 dlg = gmEditArea.cGenericEditAreaDlg2(parent = parent, id = -1, edit_area = ea, single_entry = single_entry) 794 dlg.SetTitle(gmTools.coalesce(bill_item, _('Adding new bill item'), _('Editing bill item'))) 795 if dlg.ShowModal() == wx.ID_OK: 796 dlg.Destroy() 797 return True 798 dlg.Destroy() 799 return False
800 #----------------------------------------------------------------
801 -def manage_bill_items(parent=None, pk_patient=None):
802 803 if parent is None: 804 parent = wx.GetApp().GetTopWindow() 805 #------------------------------------------------------------ 806 def edit(item=None): 807 return edit_bill_item(parent = parent, bill_item = item, single_entry = (item is not None))
808 #------------------------------------------------------------ 809 def delete(item): 810 if item.is_in_use is not None: 811 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete already invoiced bill items.'), beep = True) 812 return False 813 gmBilling.delete_bill_item(pk_bill_item = item['pk_bill_item']) 814 return True 815 #------------------------------------------------------------ 816 def get_tooltip(item): 817 if item is None: 818 return None 819 return item.format() 820 #------------------------------------------------------------ 821 def refresh(lctrl): 822 b_items = gmBilling.get_bill_items(pk_patient = pk_patient) 823 items = [ [ 824 gmDateTime.pydt_strftime(b['date_to_bill'], '%x', accuracy = gmDateTime.acc_days), 825 b['unit_count'], 826 u'%s: %s%s' % (b['billable_code'], b['billable_description'], gmTools.coalesce(b['item_detail'], u'', u' - %s')), 827 u'%s %s (%s %s %s%s%s)' % ( 828 b['total_amount'], 829 b['currency'], 830 b['unit_count'], 831 gmTools.u_multiply, 832 b['net_amount_per_unit'], 833 gmTools.u_multiply, 834 b['amount_multiplier'] 835 ), 836 u'%s %s (%s%%)' % ( 837 b['vat'], 838 b['currency'], 839 b['vat_multiplier'] * 100 840 ), 841 u'%s (%s)' % (b['catalog_short'], b['catalog_version']), 842 b['pk_bill_item'] 843 ] for b in b_items ] 844 lctrl.set_string_items(items) 845 lctrl.set_data(b_items) 846 #------------------------------------------------------------ 847 gmListWidgets.get_choices_from_list ( 848 parent = parent, 849 #msg = msg, 850 caption = _('Showing bill items.'), 851 columns = [_('Date'), _('Count'), _('Description'), _('Value'), _('VAT'), _('Catalog'), u'#'], 852 single_selection = True, 853 new_callback = edit, 854 edit_callback = edit, 855 delete_callback = delete, 856 refresh_callback = refresh, 857 list_tooltip_callback = get_tooltip 858 ) 859 860 #------------------------------------------------------------
861 -class cPersonBillItemsManagerPnl(gmListWidgets.cGenericListManagerPnl):
862 """A list for managing a patient's bill items. 863 864 Does NOT act on/listen to the current patient. 865 """
866 - def __init__(self, *args, **kwargs):
867 868 try: 869 self.__identity = kwargs['identity'] 870 del kwargs['identity'] 871 except KeyError: 872 self.__identity = None 873 874 gmListWidgets.cGenericListManagerPnl.__init__(self, *args, **kwargs) 875 876 self.new_callback = self._add_item 877 self.edit_callback = self._edit_item 878 self.delete_callback = self._del_item 879 self.refresh_callback = self.refresh 880 881 self.__show_non_invoiced_only = True 882 883 self.__init_ui() 884 self.refresh()
885 #-------------------------------------------------------- 886 # external API 887 #--------------------------------------------------------
888 - def refresh(self, *args, **kwargs):
889 if self.__identity is None: 890 self._LCTRL_items.set_string_items() 891 return 892 893 b_items = gmBilling.get_bill_items(pk_patient = self.__identity.ID, non_invoiced_only = self.__show_non_invoiced_only) 894 items = [ [ 895 gmDateTime.pydt_strftime(b['date_to_bill'], '%x', accuracy = gmDateTime.acc_days), 896 b['unit_count'], 897 u'%s: %s%s' % (b['billable_code'], b['billable_description'], gmTools.coalesce(b['item_detail'], u'', u' - %s')), 898 u'%s %s' % ( 899 b['total_amount'], 900 b['currency'] 901 ), 902 u'%s %s (%s%%)' % ( 903 b['vat'], 904 b['currency'], 905 b['vat_multiplier'] * 100 906 ), 907 u'%s (%s)' % (b['catalog_short'], b['catalog_version']), 908 u'%s %s %s %s %s' % ( 909 b['unit_count'], 910 gmTools.u_multiply, 911 b['net_amount_per_unit'], 912 gmTools.u_multiply, 913 b['amount_multiplier'] 914 ), 915 gmTools.coalesce(b['pk_bill'], gmTools.u_diameter), 916 b['pk_encounter_to_bill'], 917 b['pk_bill_item'] 918 ] for b in b_items ] 919 920 self._LCTRL_items.set_string_items(items = items) 921 self._LCTRL_items.set_column_widths() 922 self._LCTRL_items.set_data(data = b_items)
923 #-------------------------------------------------------- 924 # internal helpers 925 #--------------------------------------------------------
926 - def __init_ui(self):
927 self._LCTRL_items.set_columns(columns = [ 928 _('Charge date'), 929 _('Count'), 930 _('Description'), 931 _('Value'), 932 _('VAT'), 933 _('Catalog'), 934 _('Count %s Value %s Factor') % (gmTools.u_multiply, gmTools.u_multiply), 935 _('Invoice'), 936 _('Encounter'), 937 u'#' 938 ]) 939 self._LCTRL_items.item_tooltip_callback = self._get_item_tooltip 940 # self.left_extra_button = ( 941 # _('Select pending'), 942 # _('Select non-invoiced (pending) items.'), 943 # self._select_pending_items 944 # ) 945 self.left_extra_button = ( 946 _('Invoice selected items'), 947 _('Create invoice from selected items.'), 948 self._invoice_selected_items 949 ) 950 self.middle_extra_button = ( 951 _('Bills'), 952 _('Browse bills of this patient.'), 953 self._browse_bills 954 ) 955 self.right_extra_button = ( 956 _('Billables'), 957 _('Browse list of billables.'), 958 self._browse_billables 959 )
960 #--------------------------------------------------------
961 - def _add_item(self):
962 return edit_bill_item(parent = self, bill_item = None, single_entry = False)
963 #--------------------------------------------------------
964 - def _edit_item(self, bill_item):
965 return edit_bill_item(parent = self, bill_item = bill_item, single_entry = True)
966 #--------------------------------------------------------
967 - def _del_item(self, item):
968 if item['pk_bill'] is not None: 969 gmDispatcher.send(signal = 'statustext', msg = _('Cannot delete already invoiced bill items.'), beep = True) 970 return False 971 go_ahead = gmGuiHelpers.gm_show_question ( 972 _( 'Do you really want to delete this\n' 973 'bill item from the patient ?'), 974 _('Deleting bill item') 975 ) 976 if not go_ahead: 977 return False 978 gmBilling.delete_bill_item(pk_bill_item = item['pk_bill_item']) 979 return True
980 #--------------------------------------------------------
981 - def _get_item_tooltip(self, item):
982 if item is None: 983 return None 984 return item.format()
985 #--------------------------------------------------------
986 - def _select_pending_items(self, item):
987 pass
988 #--------------------------------------------------------
989 - def _invoice_selected_items(self, item):
990 bill_items = self._LCTRL_items.get_selected_item_data() 991 bill = create_bill_from_items(bill_items) 992 if bill is None: 993 return 994 if bill['pk_receiver_address'] is None: 995 gmGuiHelpers.gm_show_error ( 996 aMessage = _( 997 'Cannot create invoice.\n' 998 '\n' 999 'No receiver address selected.' 1000 ), 1001 aTitle = _('Creating invoice') 1002 ) 1003 return 1004 if bill['close_date'] is None: 1005 bill['close_date'] = gmDateTime.pydt_now_here() 1006 bill.save() 1007 create_invoice_from_bill(parent = self, bill = bill, print_it = True, keep_a_copy = True)
1008 #--------------------------------------------------------
1009 - def _browse_billables(self, item):
1010 manage_billables(parent = self) 1011 return False
1012 #--------------------------------------------------------
1013 - def _browse_bills(self, item):
1014 manage_bills(parent = self, patient = self.__identity)
1015 #-------------------------------------------------------- 1016 # properties 1017 #--------------------------------------------------------
1018 - def _get_identity(self):
1019 return self.__identity
1020
1021 - def _set_identity(self, identity):
1022 self.__identity = identity 1023 self.refresh()
1024 1025 identity = property(_get_identity, _set_identity) 1026 #--------------------------------------------------------
1028 return self.__show_non_invoiced_only
1029
1030 - def _set_show_non_invoiced_only(self, value):
1031 self.__show_non_invoiced_only = value 1032 self.refresh()
1033 1034 show_non_invoiced_only = property(_get_show_non_invoiced_only, _set_show_non_invoiced_only)
1035 1036 #------------------------------------------------------------ 1037 from Gnumed.wxGladeWidgets import wxgBillItemEAPnl 1038
1039 -class cBillItemEAPnl(wxgBillItemEAPnl.wxgBillItemEAPnl, gmEditArea.cGenericEditAreaMixin):
1040
1041 - def __init__(self, *args, **kwargs):
1042 1043 try: 1044 data = kwargs['bill_item'] 1045 del kwargs['bill_item'] 1046 except KeyError: 1047 data = None 1048 1049 wxgBillItemEAPnl.wxgBillItemEAPnl.__init__(self, *args, **kwargs) 1050 gmEditArea.cGenericEditAreaMixin.__init__(self) 1051 1052 self.mode = 'new' 1053 self.data = data 1054 if data is not None: 1055 self.mode = 'edit' 1056 1057 self.__init_ui()
1058 #----------------------------------------------------------------
1059 - def __init_ui(self):
1060 self._PRW_encounter.set_context(context = 'patient', val = gmPerson.gmCurrentPatient().ID) 1061 self._PRW_billable.add_callback_on_selection(self._on_billable_selected)
1062 #---------------------------------------------------------------- 1063 # generic Edit Area mixin API 1064 #----------------------------------------------------------------
1065 - def _valid_for_save(self):
1066 1067 validity = True 1068 1069 if self._TCTRL_factor.GetValue().strip() == u'': 1070 validity = False 1071 self.display_tctrl_as_valid(tctrl = self._TCTRL_factor, valid = False) 1072 self._TCTRL_factor.SetFocus() 1073 else: 1074 converted, factor = gmTools.input2decimal(self._TCTRL_factor.GetValue()) 1075 if not converted: 1076 validity = False 1077 self.display_tctrl_as_valid(tctrl = self._TCTRL_factor, valid = False) 1078 self._TCTRL_factor.SetFocus() 1079 else: 1080 self.display_tctrl_as_valid(tctrl = self._TCTRL_factor, valid = True) 1081 1082 if self._TCTRL_amount.GetValue().strip() == u'': 1083 validity = False 1084 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False) 1085 self._TCTRL_amount.SetFocus() 1086 else: 1087 converted, factor = gmTools.input2decimal(self._TCTRL_amount.GetValue()) 1088 if not converted: 1089 validity = False 1090 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = False) 1091 self._TCTRL_amount.SetFocus() 1092 else: 1093 self.display_tctrl_as_valid(tctrl = self._TCTRL_amount, valid = True) 1094 1095 if self._TCTRL_count.GetValue().strip() == u'': 1096 validity = False 1097 self.display_tctrl_as_valid(tctrl = self._TCTRL_count, valid = False) 1098 self._TCTRL_count.SetFocus() 1099 else: 1100 converted, factor = gmTools.input2decimal(self._TCTRL_count.GetValue()) 1101 if not converted: 1102 validity = False 1103 self.display_tctrl_as_valid(tctrl = self._TCTRL_count, valid = False) 1104 self._TCTRL_count.SetFocus() 1105 else: 1106 self.display_tctrl_as_valid(tctrl = self._TCTRL_count, valid = True) 1107 1108 if self._PRW_date.is_valid_timestamp(allow_empty = True): 1109 self._PRW_date.display_as_valid(True) 1110 else: 1111 validity = False 1112 self._PRW_date.display_as_valid(False) 1113 self._PRW_date.SetFocus() 1114 1115 if self._PRW_encounter.GetData() is None: 1116 validity = False 1117 self._PRW_encounter.display_as_valid(False) 1118 self._PRW_encounter.SetFocus() 1119 else: 1120 self._PRW_encounter.display_as_valid(True) 1121 1122 if self._PRW_billable.GetData() is None: 1123 validity = False 1124 self._PRW_billable.display_as_valid(False) 1125 self._PRW_billable.SetFocus() 1126 else: 1127 self._PRW_billable.display_as_valid(True) 1128 1129 return validity
1130 #----------------------------------------------------------------
1131 - def _save_as_new(self):
1132 data = gmBilling.create_bill_item ( 1133 pk_encounter = gmPerson.gmCurrentPatient().emr.active_encounter['pk_encounter'], 1134 pk_billable = self._PRW_billable.GetData(), 1135 pk_staff = gmStaff.gmCurrentProvider()['pk_staff'] # should be settable ! 1136 ) 1137 data['raw_date_to_bill'] = self._PRW_date.GetData() 1138 converted, data['unit_count'] = gmTools.input2decimal(self._TCTRL_count.GetValue()) 1139 converted, data['net_amount_per_unit'] = gmTools.input2decimal(self._TCTRL_amount.GetValue()) 1140 converted, data['amount_multiplier'] = gmTools.input2decimal(self._TCTRL_factor.GetValue()) 1141 data['item_detail'] = self._TCTRL_comment.GetValue().strip() 1142 data.save() 1143 1144 self.data = data 1145 return True
1146 #----------------------------------------------------------------
1147 - def _save_as_update(self):
1148 self.data['pk_encounter_to_bill'] = self._PRW_encounter.GetData() 1149 self.data['raw_date_to_bill'] = self._PRW_date.GetData() 1150 converted, self.data['unit_count'] = gmTools.input2decimal(self._TCTRL_count.GetValue()) 1151 converted, self.data['net_amount_per_unit'] = gmTools.input2decimal(self._TCTRL_amount.GetValue()) 1152 converted, self.data['amount_multiplier'] = gmTools.input2decimal(self._TCTRL_factor.GetValue()) 1153 self.data['item_detail'] = self._TCTRL_comment.GetValue().strip() 1154 return self.data.save()
1155 #----------------------------------------------------------------
1156 - def _refresh_as_new(self):
1157 self._PRW_billable.SetText() 1158 self._PRW_encounter.set_from_instance(gmPerson.gmCurrentPatient().emr.active_encounter) 1159 self._PRW_date.SetData() 1160 self._TCTRL_count.SetValue(u'1') 1161 self._TCTRL_amount.SetValue(u'') 1162 self._LBL_currency.SetLabel(gmTools.u_euro) 1163 self._TCTRL_factor.SetValue(u'1') 1164 self._TCTRL_comment.SetValue(u'') 1165 1166 self._PRW_billable.Enable() 1167 self._PRW_billable.SetFocus()
1168 #----------------------------------------------------------------
1170 self._PRW_billable.SetText() 1171 self._TCTRL_count.SetValue(u'1') 1172 self._TCTRL_amount.SetValue(u'') 1173 self._TCTRL_comment.SetValue(u'') 1174 1175 self._PRW_billable.Enable() 1176 self._PRW_billable.SetFocus()
1177 #----------------------------------------------------------------
1178 - def _refresh_from_existing(self):
1179 self._PRW_billable.set_from_pk(self.data['pk_billable']) 1180 self._PRW_encounter.set_from_instance(gmPerson.gmCurrentPatient().emr.active_encounter) 1181 self._PRW_date.SetData(data = self.data['raw_date_to_bill']) 1182 self._TCTRL_count.SetValue(u'%s' % self.data['unit_count']) 1183 self._TCTRL_amount.SetValue(u'%s' % self.data['net_amount_per_unit']) 1184 self._LBL_currency.SetLabel(self.data['currency']) 1185 self._TCTRL_factor.SetValue(u'%s' % self.data['amount_multiplier']) 1186 self._TCTRL_comment.SetValue(gmTools.coalesce(self.data['item_detail'], u'')) 1187 1188 self._PRW_billable.Disable() 1189 self._PRW_date.SetFocus()
1190 #----------------------------------------------------------------
1191 - def _on_billable_selected(self, item):
1192 if item is None: 1193 return 1194 if self._TCTRL_amount.GetValue().strip() != u'': 1195 return 1196 val = u'%s' % self._PRW_billable.GetData(as_instance = True)['raw_amount'] 1197 wx.CallAfter(self._TCTRL_amount.SetValue, val)
1198 1199 #============================================================ 1200 # a plugin for billing 1201 #------------------------------------------------------------ 1202 from Gnumed.wxGladeWidgets import wxgBillingPluginPnl 1203
1204 -class cBillingPluginPnl(wxgBillingPluginPnl.wxgBillingPluginPnl, gmRegetMixin.cRegetOnPaintMixin):
1205 - def __init__(self, *args, **kwargs):
1206 1207 wxgBillingPluginPnl.wxgBillingPluginPnl.__init__(self, *args, **kwargs) 1208 gmRegetMixin.cRegetOnPaintMixin.__init__(self) 1209 self.__register_interests()
1210 #-----------------------------------------------------
1211 - def __reset_ui(self):
1212 self._PNL_bill_items.identity = None 1213 self._CHBOX_show_non_invoiced_only.SetValue(1) 1214 self._PRW_billable.SetText(u'', None) 1215 self._TCTRL_factor.SetValue(u'1.0') 1216 self._TCTRL_factor.Disable() 1217 self._TCTRL_details.SetValue(u'') 1218 self._TCTRL_details.Disable()
1219 #----------------------------------------------------- 1220 # event handling 1221 #-----------------------------------------------------
1222 - def __register_interests(self):
1223 gmDispatcher.connect(signal = u'pre_patient_selection', receiver = self._on_pre_patient_selection) 1224 gmDispatcher.connect(signal = u'post_patient_selection', receiver = self._on_post_patient_selection) 1225 1226 gmDispatcher.connect(signal = u'bill_item_mod_db', receiver = self._on_bill_item_modified) 1227 1228 self._PRW_billable.add_callback_on_selection(self._on_billable_selected_in_prw)
1229 #-----------------------------------------------------
1230 - def _on_pre_patient_selection(self):
1231 wx.CallAfter(self.__reset_ui)
1232 #-----------------------------------------------------
1233 - def _on_post_patient_selection(self):
1234 wx.CallAfter(self._schedule_data_reget)
1235 #-----------------------------------------------------
1236 - def _on_bill_item_modified(self):
1237 wx.CallAfter(self._schedule_data_reget)
1238 #-----------------------------------------------------
1240 self._PNL_bill_items.show_non_invoiced_only = self._CHBOX_show_non_invoiced_only.GetValue()
1241 #--------------------------------------------------------
1242 - def _on_insert_bill_item_button_pressed(self, event):
1243 val = self._TCTRL_factor.GetValue().strip() 1244 if val == u'': 1245 factor = 1.0 1246 else: 1247 converted, factor = gmTools.input2decimal(val) 1248 if not converted: 1249 gmGuiHelpers.gm_show_warning ( 1250 _('"Factor" must be a number\n\nCannot insert bill item.'), 1251 _('Inserting bill item') 1252 ) 1253 return False 1254 bill_item = gmBilling.create_bill_item ( 1255 pk_encounter = gmPerson.gmCurrentPatient().emr.active_encounter['pk_encounter'], 1256 pk_billable = self._PRW_billable.GetData(), 1257 pk_staff = gmStaff.gmCurrentProvider()['pk_staff'] 1258 ) 1259 bill_item['amount_multiplier'] = factor 1260 bill_item['item_detail'] = self._TCTRL_details.GetValue() 1261 bill_item.save() 1262 1263 self._TCTRL_details.SetValue(u'') 1264 1265 return True
1266 #--------------------------------------------------------
1267 - def _on_billable_selected_in_prw(self, billable):
1268 if billable is None: 1269 self._TCTRL_factor.Disable() 1270 self._TCTRL_details.Disable() 1271 self._BTN_insert_item.Disable() 1272 else: 1273 self._TCTRL_factor.Enable() 1274 self._TCTRL_details.Enable() 1275 self._BTN_insert_item.Enable()
1276 #----------------------------------------------------- 1277 # reget-on-paint mixin API 1278 #-----------------------------------------------------
1279 - def _populate_with_data(self):
1280 self._PNL_bill_items.identity = gmPerson.gmCurrentPatient() 1281 return True
1282 #============================================================ 1283 # main 1284 #------------------------------------------------------------ 1285 if __name__ == '__main__': 1286 1287 if len(sys.argv) < 2: 1288 sys.exit() 1289 1290 if sys.argv[1] != 'test': 1291 sys.exit() 1292 1293 from Gnumed.pycommon import gmI18N 1294 gmI18N.activate_locale() 1295 gmI18N.install_domain(domain = 'gnumed') 1296 1297 #---------------------------------------- 1298 app = wx.PyWidgetTester(size = (600, 600)) 1299 #app.SetWidget(cATCPhraseWheel, -1) 1300 #app.SetWidget(cSubstancePhraseWheel, -1) 1301 app.MainLoop() 1302