def test_cancel_order(self, new_store, yesno): new_store.return_value = self.store yesno.return_value = True self.clean_domain( [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) purchase.status = PurchaseOrder.ORDER_PENDING api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.Cancel) yesno.assert_called_once_with( u'The selected order will be ' u'cancelled.', gtk.RESPONSE_YES, u"Cancel order", u"Don't cancel") self.assertEquals(purchase.status, PurchaseOrder.ORDER_CANCELLED)
def testCommissionCreateAtEnd(self): api.sysparam(self.store).update_parameter( u'SALE_PAY_COMMISSION_WHEN_CONFIRMED', u'0') sale = self.create_sale() self.add_product(sale, quantity=1, price=200) sale.order() self.add_payments(sale, method_type=u'bill', installments=10) for p in sale.payments: self.assertEqual( self.store.find(Commission, payment=p).count(), 0) sale.confirm() transaction = IPaymentTransaction(sale) fake = lambda p: None # Mimic out old behaviour of only creating commissions for payments # when all payments on a sale are set as paid. with mock.patch.object(transaction, 'create_commission', new=fake): for p in sale.payments: # Confirming should not create commissions self.assertEqual( self.store.find(Commission, payment=p).count(), 0) # Since we are mimicking the old behaviour, commission # should not be created here. p.pay() self.assertEqual( self.store.find(Commission, payment=p).count(), 0) # Setting as paid should create all the missing commissions sale.set_paid() for p in sale.payments: self.assertEqual( self.store.find(Commission, payment=p).count(), 1)
def test_cancel_workorder_confirm(self, new_store, yesno): new_store.return_value = self.store self.clean_domain([WorkOrderItem, WorkOrder]) workorder = self.create_workorder() api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(MaintenanceApp, u'maintenance') olist = app.results olist.select(olist[0]) # Initial status for the order is Opened self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED) self.assertSensitive(app, ['Cancel']) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): # Click the cancel order, and confirm the change yesno.return_value = True self.activate(app.Cancel) yesno.assert_called_once_with( u"This will cancel the selected " u"order. Are you sure?", gtk.RESPONSE_NO, u"Cancel order", u"Don't cancel") # Status should be updated to cancelled. self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
def test_cancel_workorder_confirm(self, new_store, yesno): new_store.return_value = self.store self.clean_domain([WorkOrderItem, WorkOrder]) workorder = self.create_workorder() api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(MaintenanceApp, u'maintenance') olist = app.results olist.select(olist[0]) # Initial status for the order is Opened self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED) self.assertSensitive(app, ['Cancel']) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): # Click the cancel order, and confirm the change yesno.return_value = True self.activate(app.Cancel) yesno.assert_called_once_with(u"This will cancel the selected " u"order. Are you sure?", gtk.RESPONSE_NO, u"Cancel order", u"Don't cancel") # Status should be updated to cancelled. self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
def test_cancel_workorder_confirm(self, new_store, run_dialog): new_store.return_value = self.store self.clean_domain([WorkOrderItem, WorkOrder]) workorder = self.create_workorder() api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(MaintenanceApp, u'maintenance') olist = app.results olist.select(olist[0]) # Initial status for the order is Opened self.assertEquals(workorder.status, WorkOrder.STATUS_OPENED) self.assertSensitive(app, ['Cancel']) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): # Click the cancel order, and confirm the change run_dialog.return_value = Note(notes=u'xxx') self.activate(app.Cancel) run_dialog.assert_called_once_with( NoteEditor, self.store, message_text=(u'This will cancel the selected order. ' u'Are you sure?'), model=Note(), mandatory=True, label_text=u'Reason') # Status should be updated to cancelled. self.assertEquals(workorder.status, WorkOrder.STATUS_CANCELLED)
def __init__(self, app, store=None): self._pages = {} self.accounts = AccountTree() AppWindow.__init__(self, app, store=store) self._tills_account = api.sysparam(self.store).TILLS_ACCOUNT self._imbalance_account = api.sysparam(self.store).IMBALANCE_ACCOUNT self._banks_account = api.sysparam(self.store).BANKS_ACCOUNT
def test_confirm_order(self, new_store, yesno): new_store.return_value = self.store yesno.return_value = True self.clean_domain([ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) purchase.status = PurchaseOrder.ORDER_PENDING api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.Confirm) yesno.assert_called_once_with(u'The selected order will be ' u'marked as sent.', gtk.RESPONSE_YES, u"Confirm order", u"Don't confirm") self.assertEquals(purchase.status, PurchaseOrder.ORDER_CONFIRMED)
def test_batch_number_suggestion(self): branch = api.get_current_branch(self.store) branch.acronym = u'AB' storable = self.create_storable(is_batch=True) storable2 = self.create_storable(is_batch=True) dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) self.assertEqual(dialog._last_entry.get_text(), '') api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'1') try: storable.register_initial_stock(1, self.create_branch(), 0, batch_number=u'123') dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) # Make sure it suggested right self.assertEqual(dialog._last_entry.get_text(), '124') spinbutton = dialog.get_spin_by_entry(dialog._last_entry) spinbutton.update(5) # Updating the spinbutton should append a new entry with the suggestion self.assertEqual(dialog._last_entry.get_text(), '125') self.click(dialog.main_dialog.ok_button) dialog = BatchIncreaseSelectionDialog(self.store, storable2, 10) # Since the dialog above was confirmed on the same store this one is, # it should consider it's batch numbers for the next suggestion self.assertEqual(dialog._last_entry.get_text(), '126') finally: api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'0')
def testCommissionCreateOnPay(self): api.sysparam(self.store).update_parameter( u'SALE_PAY_COMMISSION_WHEN_CONFIRMED', u'0') sale = self.create_sale() self.add_product(sale, quantity=1, price=200) sale.order() self.add_payments(sale, method_type=u'bill', installments=10) for p in sale.payments: self.assertEqual( self.store.find(Commission, payment=p).count(), 0) sale.confirm() for p in sale.payments: # Confirming should not create commissions self.assertEqual( self.store.find(Commission, payment=p).count(), 0) # Paying should create the commission p.pay() self.assertEqual( self.store.find(Commission, payment=p).count(), 1) # Setting as paid should not create another commission sale.set_paid() for p in sale.payments: self.assertEqual( self.store.find(Commission, payment=p).count(), 1)
def __init__(self, window, store=None): # Account id -> TransactionPage self._pages = {} self.accounts = AccountTree() ShellApp.__init__(self, window, store=store) self._tills_account = api.sysparam(self.store).TILLS_ACCOUNT self._imbalance_account = api.sysparam(self.store).IMBALANCE_ACCOUNT self._banks_account = api.sysparam(self.store).BANKS_ACCOUNT
def test_print_report(self, print_report): api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') self.activate(app.window.Print) self.assertEquals(print_report.call_count, 1) args, kwargs = print_report.call_args report, results, views = args self.assertEquals(report, PurchaseReport) self.assertTrue(isinstance(results, SearchResultListView)) for view in views: self.assertTrue(isinstance(view, PurchaseOrderView))
def test_print_report(self, print_report): api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') self.activate(app.launcher.Print) self.assertEquals(print_report.call_count, 1) args, kwargs = print_report.call_args report, results, views = args self.assertEquals(report, PurchaseReport) self.assertTrue(isinstance(results, SearchResults)) for view in views: self.assertTrue(isinstance(view, PurchaseOrderView))
def test_batch_number_suggestion_synchronized_mode(self): branch = api.get_current_branch(self.store) branch.acronym = u'AB' storable = self.create_storable(is_batch=True) storable2 = self.create_storable(is_batch=True) dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) self.assertEqual(dialog._last_entry.get_text(), '') try: api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'1') # We need to do this by hand sincr update_parameter won't let us # update value for some parameters (SYNCHRONIZED_MODE is one of them) api.sysparam(self.store).SYNCHRONIZED_MODE = u'1' api.sysparam(self.store).rebuild_cache_for(u'SYNCHRONIZED_MODE') storable.register_initial_stock(1, self.create_branch(), 0, batch_number=u'130') dialog = BatchIncreaseSelectionDialog(self.store, storable, 10) # Make sure it suggested right self.assertEqual(dialog._last_entry.get_text(), '131-AB') spinbutton = dialog.get_spin_by_entry(dialog._last_entry) spinbutton.update(5) # Updating the spinbutton should append a new entry with the suggestion self.assertEqual(dialog._last_entry.get_text(), '132-AB') self.click(dialog.main_dialog.ok_button) dialog = BatchIncreaseSelectionDialog(self.store, storable2, 10) # Since the dialog above was confirmed on the same store this one is, # it should consider it's batch numbers for the next suggestion self.assertEqual(dialog._last_entry.get_text(), '133-AB') branch.acronym = None spinbutton = dialog.get_spin_by_entry(dialog._last_entry) # FIXME: Why is this not working? If i put a print before .update # and one after, I can see the traceback raises between the prints, # GUITest will say that there was an unhandled exception (this one) # and assertRaisesRegexp will say that ValueError wasn't raised. WTF??? #with self.assertRaisesRegexp( # ValueError, # ("branch 'Moda Stoq' needs an acronym since we are on " # "synchronized mode")): # spinbutton.update(1) finally: api.sysparam(self.store).update_parameter(u'SUGGEST_BATCH_NUMBER', u'0') api.sysparam(self.store).SYNCHRONIZED_MODE = u'0' api.sysparam(self.store).rebuild_cache_for(u'SYNCHRONIZED_MODE')
def _get_next_batch_number(self): max_db = StorableBatch.get_max_value(self.store, StorableBatch.batch_number) max_used = max_value_for(self._get_used_batches() | set([max_db])) if not api.sysparam(self.store).SYNCHRONIZED_MODE: return next_value_for(max_used) # On synchronized mode we need to append the branch acronym # to avoid conflicts max_used_list = max_used.split('-') if len(max_used_list) == 1: # '123' max_used = max_used_list[0] elif len(max_used_list) == 2: # '123-AB' max_used = max_used_list[0] else: # '123-456-AB' max_used = ''.join(max_used_list[:-1]) branch = api.get_current_branch(self.store) if not branch.acronym: raise ValueError("branch '%s' needs an acronym since we are on " "synchronized mode" % (branch.get_description(),)) return '-'.join([next_value_for(max_used), branch.acronym])
def get_batch_item(self, batch): if batch is not None: return batch.batch_number if not api.sysparam(self.store).SUGGEST_BATCH_NUMBER: return None return self._get_next_batch_number()
def cookie_login(self): if api.sysparam(api.get_default_store()).DISABLE_COOKIES: log.info("Cookies disable by parameter") return cookie_file = get_utility(ICookieFile) try: username, password = cookie_file.get() except CookieError: log.info("Not using cookie based login") return def is_md5(password): # This breaks for passwords that are 32 characters long, # uses only digits and lowercase a-f, pretty unlikely as # real-world password if len(password) != 32: return False for c in '1234567890abcdef': password = password.replace(c, '') return password == '' # Migrate old passwords to md5 hashes. if not is_md5(password): password = LoginUser.hash(password) cookie_file.store(username, password) try: user = self._check_user(username, password) except (LoginError, UserProfileError, DatabaseError) as e: log.info("Cookie login failed: %r" % e) return log.info("Logging in using cookie credentials") return user
def _get_sellable(self): barcode = self.barcode.get_text() if not barcode: raise StoqlibError("_get_sellable needs a barcode") barcode = unicode(barcode) fmt = api.sysparam(self.store).SCALE_BARCODE_FORMAT # Check if this barcode is from a scale info = parse_barcode(barcode, fmt) if info: barcode = info.code weight = info.weight sellable = self.store.find(Sellable, barcode=barcode, status=Sellable.STATUS_AVAILABLE).one() # If the barcode didnt match, maybe the user typed the product code if not sellable: sellable = self.store.find(Sellable, code=barcode, status=Sellable.STATUS_AVAILABLE).one() # If the barcode has the price information, we need to calculate the # corresponding weight. if info and sellable and info.mode == BarcodeInfo.MODE_PRICE: weight = info.price / sellable.price if info and sellable: self.quantity.set_value(weight) return sellable
def run_embedded(self, appdesc, app_window, params=None): app = self._load_app(appdesc, app_window) app.launcher = app_window self._current_app = app self._appname = appdesc.name if appdesc.name in self._blocked_apps: app_window.show() return app.run(params) # Possibly correct window position (livecd workaround for small # screens) from stoqlib.lib.pluginmanager import get_plugin_manager manager = get_plugin_manager() from stoqlib.api import api if (api.sysparam(api.get_default_store()).DEMO_MODE and manager.is_active(u'ecf')): pos = app.main_window.toplevel.get_position() if pos[0] < 220: app.main_window.toplevel.move(220, pos[1]) return app
def on_estimated_start__validate(self, widget, value): sysparam_ = api.sysparam(self.store) if (value < datetime.date.today() and not sysparam_.ALLOW_OUTDATED_OPERATIONS): return ValidationError(u"The start date cannot be on the past") self.estimated_finish.validate(force=True)
def on_estimated_start__validate(self, widget, value): sysparam_ = api.sysparam(self.store) if (value < localtoday().date() and not sysparam_.ALLOW_OUTDATED_OPERATIONS): return ValidationError(u"The start date cannot be on the past") self.estimated_finish.validate(force=True)
def get_namespace(self): store = self.loan.store sysparam_ = api.sysparam(store) order_identifier = unicode(self.loan.identifier) print_promissory_note = sysparam_.PRINT_PROMISSORY_NOTE_ON_LOAN branch = api.get_current_branch(store) drawer_person = self.loan.branch.person drawee_person = self.loan.client.person emission_address = branch.person.get_main_address() emission_location = emission_address.city_location promissory_data = Settable( order_identifier=order_identifier, payment_number=None, drawee=drawee_person.name, drawer=drawer_person.name, drawee_document=self._get_person_document(drawee_person), drawer_document=self._get_person_document(drawer_person), drawee_address=self._get_person_address(drawee_person), drawer_address=self._get_person_address(drawer_person), due_date=self.loan.expire_date, value=self.loan.get_total_amount(), emission_city=emission_location.city, emission_date=datetime.date.today(), ) return dict( subtitle=_("Loan number: %s") % order_identifier, loan=self.loan, print_promissory_note=print_promissory_note, promissory_data=promissory_data, )
def create_ui(self): if api.sysparam(self.store).SMART_LIST_LOADING: self.search.enable_lazy_search() self.popup = self.uimanager.get_widget('/StockSelection') self.window.add_new_items([self.NewReceiving, self.NewTransfer, self.NewStockDecrease, self.LoanNew]) self.window.add_search_items([ self.SearchStockItems, self.SearchStockDecrease, self.SearchClosedStockItems, self.SearchProductHistory, self.SearchPurchasedStockItems, self.SearchTransfer, ]) self.window.Print.set_tooltip( _("Print a report of these products")) self._inventory_widgets = [self.NewTransfer, self.NewReceiving, self.StockInitial, self.NewStockDecrease, self.LoanNew, self.LoanClose] self.register_sensitive_group(self._inventory_widgets, lambda: not self.has_open_inventory()) self.image_viewer = None self.image = gtk.Image() self.edit_button = self.uimanager.get_widget('/toolbar/AppToolbarPH/EditProduct') self.edit_button.set_icon_widget(self.image) self.image.show() self.search.set_summary_label(column='stock', label=_('<b>Stock Total:</b>'), format='<b>%s</b>', parent=self.get_statusbar_message_area())
def create_ui(self): if api.sysparam(self.store).SMART_LIST_LOADING: self.search.enable_lazy_search() self.window.add_new_items([ self.NewOrder, self.NewQuote, self.NewProduct, self.NewConsignment]) self.window.add_search_items([ self.Products, self.Suppliers, self.SearchQuotes, self.Services]) self.search.set_summary_label(column='total', label=('<b>%s</b>' % api.escape(_('Orders total:'))), format='<b>%s</b>', parent=self.get_statusbar_message_area()) self.results.set_selection_mode(gtk.SELECTION_MULTIPLE) self.Confirm.set_sensitive(False) self._inventory_widgets = [self.NewConsignment, self.CloseInConsignment] self.register_sensitive_group(self._inventory_widgets, lambda: not self.has_open_inventory())
def get_namespace(self): store = self.loan.store sysparam_ = api.sysparam(store) order_identifier = unicode(self.loan.identifier) print_promissory_note = sysparam_.PRINT_PROMISSORY_NOTE_ON_LOAN branch = api.get_current_branch(store) drawer_person = self.loan.branch.person drawee_person = self.loan.client.person emission_address = branch.person.get_main_address() emission_location = emission_address.city_location promissory_data = Settable( order_identifier=order_identifier, payment_number=None, drawee=drawee_person.name, drawer=branch.get_description(), drawee_document=self._get_person_document(drawee_person), drawer_document=self._get_person_document(drawer_person), drawee_address=self._get_person_address(drawee_person), drawer_address=self._get_person_address(drawer_person), due_date=self.loan.expire_date, value=self.loan.get_total_amount(), emission_city=emission_location.city, emission_date=datetime.date.today(), ) return dict( subtitle=_("Loan number: %s") % order_identifier, loan=self.loan, print_promissory_note=print_promissory_note, promissory_data=promissory_data, )
def _pay(self, payable_views): """ Pay a list of items from a payable_views, note that the list of payable_views must reference the same order @param payables_views: a list of payable_views """ assert self._can_pay(payable_views) # Do not allow confirming the payment if the purchase was not # completely received. purchase_order = payable_views[0].purchase if (purchase_order and api.sysparam(self.store).BLOCK_INCOMPLETE_PURCHASE_PAYMENTS and not purchase_order.status == PurchaseOrder.ORDER_CLOSED): return warning(_("Can't confirm the payment if the purchase " "is not completely received yet.")) with api.trans() as store: payments = [store.fetch(view.payment) for view in payable_views] run_dialog(PurchasePaymentConfirmSlave, self, store, payments=payments) if store.committed: # We need to refresh the whole list as the payment(s) can possibly # disappear for the selected view self.refresh() self._update_widgets()
def cookie_login(self): if api.sysparam(api.get_default_store()).DISABLE_COOKIES: log.info("Cookies disable by parameter") return cookie_file = get_utility(ICookieFile) try: username, password = cookie_file.get() except CookieError: log.info("Not using cookie based login") return def is_md5(password): # This breaks for passwords that are 32 characters long, # uses only digits and lowercase a-f, pretty unlikely as # real-world password if len(password) != 32: return False for c in '1234567890abcdef': password = password.replace(c, '') return password == '' # Migrate old passwords to md5 hashes. if not is_md5(password): password = _encrypt_password(password) cookie_file.store(username, password) try: user = self._check_user(username, password) except (LoginError, UserProfileError, DatabaseError) as e: log.info("Cookie login failed: %r" % e) return log.info("Logging in using cookie credentials") return user
def _pay(self, payable_views): """ Pay a list of items from a payable_views, note that the list of payable_views must reference the same order @param payables_views: a list of payable_views """ assert self._can_pay(payable_views) # Do not allow confirming the payment if the purchase was not # completely received. purchase_order = payable_views[0].purchase if (purchase_order and api.sysparam(self.store).BLOCK_INCOMPLETE_PURCHASE_PAYMENTS and not purchase_order.status == PurchaseOrder.ORDER_CLOSED): return warning( _("Can't confirm the payment if the purchase " "is not completely received yet.")) with api.trans() as store: payments = [store.fetch(view.payment) for view in payable_views] run_dialog(PurchasePaymentConfirmSlave, self, store, payments=payments) if store.committed: # We need to refresh the whole list as the payment(s) can possibly # disappear for the selected view self.refresh() self._update_widgets()
def _delete_account(self, account_view): store = api.new_store() account = store.fetch(account_view.account) methods = PaymentMethod.get_by_account(store, account) if methods.count() > 0: if not yesno( _('This account is used in at least one payment method.\n' 'To be able to delete it the payment methods needs to be' 're-configured first'), gtk.RESPONSE_NO, _("Configure payment methods"), _("Keep account")): store.close() return elif not yesno( _('Are you sure you want to remove account "%s" ?') % ( (account_view.description, )), gtk.RESPONSE_NO, _("Remove account"), _("Keep account")): store.close() return if account_view.id in self._pages: account_page = self._pages[account_view.id] self._close_page(account_page) self.accounts.remove(account_view) self.accounts.flush() imbalance = api.sysparam(store).IMBALANCE_ACCOUNT for method in methods: method.destination_account = imbalance account.remove(store) store.commit(close=True)
def _search_product(self): hide_cost_column = not api.sysparam( self.store).SHOW_COST_COLUMN_IN_SALES self.run_dialog(ProductSearch, self.store, hide_footer=True, hide_toolbar=True, hide_cost_column=hide_cost_column)
def test_sellable_tax_constant(): # pragma nocover ec = api.prepare_test() tax_constant = api.sysparam(ec.store).DEFAULT_PRODUCT_TAX_CONSTANT run_dialog(SellableTaxConstantEditor, parent=None, store=ec.store, model=tax_constant) print(tax_constant)
def get_uri(self): if locale.getlocale()[0] == 'pt_BR' or platform.system() == 'Windows': content = environ.find_resource('html', 'welcome-pt_BR.html') else: content = environ.find_resource('html', 'welcome.html') if api.sysparam(api.get_default_store()).DEMO_MODE: content += '?demo-mode' return 'file:///' + content
def create_ui(self): if api.sysparam(self.store).SMART_LIST_LOADING: self.search.enable_lazy_search() self.results.set_selection_mode(gtk.SELECTION_MULTIPLE) self.search.set_summary_label(column='value', label='<b>%s</b>' % (_('Total'), ), format='<b>%s</b>', parent=self.get_statusbar_message_area()) self.results.set_cell_data_func(self._on_results__cell_data_func)
def _create_sale(self, store): user = api.get_current_user(store) branch = api.get_current_branch(store) salesperson = user.person.salesperson cfop = api.sysparam(store).DEFAULT_SALES_CFOP group = PaymentGroup(store=store) sale = Sale( store=store, branch=branch, salesperson=salesperson, group=group, cfop=cfop, coupon_id=None, operation_nature=api.sysparam(store).DEFAULT_OPERATION_NATURE) if self._delivery: sale.client = store.fetch(self._delivery.client) sale.storeporter = store.fetch(self._delivery.transporter) delivery = Delivery( store=store, address=store.fetch(self._delivery.address), transporter=store.fetch(self._delivery.transporter), ) else: delivery = None sale.client = self._suggested_client for fake_sale_item in self.sale_items: sale_item = sale.add_sellable( store.fetch(fake_sale_item.sellable), price=fake_sale_item.price, quantity=fake_sale_item.quantity, quantity_decreased=fake_sale_item.quantity_decreased, batch=store.fetch(fake_sale_item.batch)) sale_item.notes = fake_sale_item.notes sale_item.estimated_fix_date = fake_sale_item.estimated_fix_date if delivery and fake_sale_item.deliver: delivery.add_item(sale_item) elif delivery and fake_sale_item == self._delivery_item: delivery.service_item = sale_item return sale
def _maybe_print_labels(self): param = api.sysparam(self.store).LABEL_TEMPLATE_PATH if not param.path: return if not yesno(_(u'Do you want to print the labels for the received products?'), gtk.RESPONSE_YES, _(u'Print labels'), _(u"Don't print")): return label_data = run_dialog(SkipLabelsEditor, self, self.store) if label_data: print_labels(label_data, self.store, self.model.purchase)
def _setup_widgets(self): quote_group = str(self.wizard.quote_group.identifier) self.quote_group.set_text(quote_group) branches = Branch.get_active_branches(self.store) self.branch_combo.prefill(api.for_person_combo(branches)) sync_mode = api.sysparam(self.store).SYNCHRONIZED_MODE self.branch_combo.set_sensitive(not sync_mode) self.notes.set_accepts_tab(False)
def setUp(self): super(TestBooklet, self).setUp() api.sysparam(self.store).BOOKLET_INSTRUCTIONS = ( u"Instruction line 1\n" u"Instruction line 2\n" u"Instruction line 3\n" u"Instruction line 4\n" # This should not appear as it's limited to 4 lines u"Instruction line 5\n")
def test_edit_quote_order(self, run_dialog): api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') purchase = self.create_purchase_order() app = self.create_app(PurchaseApp, u'purchase') for purchase in app.results: purchase.open_date = datetime.datetime(2012, 1, 1) olist = app.results olist.select(olist[0]) with mock.patch('stoq.gui.purchase.api', new=self.fake.api): self.fake.set_retval(purchase) self.activate(app.NewQuote) self.assertEquals(run_dialog.call_count, 1) args, kwargs = run_dialog.call_args wizard, store, edit_mode = args self.assertEquals(wizard, QuotePurchaseWizard) self.assertTrue(store is not None) self.assertEquals(edit_mode, None)
def setUp(self): super(TestBooklet, self).setUp() api.sysparam(self.store).BOOKLET_INSTRUCTIONS = ( u"Instruction line 1\n" u"Instruction line 2\n" u"Instruction line 3\n" u"Instruction line 4\n" # This should not appear as it's limited to 4 lines u"Instruction line 5\n" )
def test_edit_quote_order(self, run_dialog): api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') purchase = self.create_purchase_order() app = self.create_app(PurchaseApp, u'purchase') for purchase in app.main_window.results: purchase.open_date = datetime.datetime(2012, 1, 1) olist = app.main_window.results olist.select(olist[0]) with mock.patch('stoq.gui.purchase.api', new=self.fake.api): self.fake.set_retval(purchase) self.activate(app.main_window.NewQuote) self.assertEquals(run_dialog.call_count, 1) args, kwargs = run_dialog.call_args wizard, store, edit_mode = args self.assertEquals(wizard, QuotePurchaseWizard) self.assertTrue(store is not None) self.assertEquals(edit_mode, None)
def _create_sale(self, store): user = api.get_current_user(store) branch = api.get_current_branch(store) salesperson = user.person.salesperson cfop = api.sysparam(store).DEFAULT_SALES_CFOP group = PaymentGroup(store=store) sale = Sale(store=store, branch=branch, salesperson=salesperson, group=group, cfop=cfop, coupon_id=None, operation_nature=api.sysparam(store).DEFAULT_OPERATION_NATURE) if self._delivery: sale.client = store.fetch(self._delivery.client) sale.storeporter = store.fetch(self._delivery.transporter) delivery = Delivery( store=store, address=store.fetch(self._delivery.address), transporter=store.fetch(self._delivery.transporter), ) else: delivery = None sale.client = self._suggested_client for fake_sale_item in self.sale_items: sale_item = sale.add_sellable( store.fetch(fake_sale_item.sellable), price=fake_sale_item.price, quantity=fake_sale_item.quantity, quantity_decreased=fake_sale_item.quantity_decreased, batch=store.fetch(fake_sale_item.batch)) sale_item.notes = fake_sale_item.notes sale_item.estimated_fix_date = fake_sale_item.estimated_fix_date if delivery and fake_sale_item.deliver: delivery.add_item(sale_item) elif delivery and fake_sale_item == self._delivery_item: delivery.service_item = sale_item return sale
def test_new_product(self, new_store, run_dialog): new_store.return_value = self.store self.clean_domain([ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) purchase.status = PurchaseOrder.ORDER_PENDING api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.main_window.results olist.select(olist[0]) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.main_window.NewProduct) run_dialog.assert_called_once_with(ProductEditor, self.store, model=None)
def test_details_dialog(self, run_dialog): self.clean_domain( [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) olist.double_click(0) self.assertEquals(run_dialog.call_count, 1) args, kwargs = run_dialog.call_args dialog, store = args self.assertEquals(dialog, PurchaseDetailsDialog) self.assertTrue(store is not None) self.assertEquals(kwargs[u'model'], purchase)
def test_details_dialog(self, run_dialog): self.clean_domain([ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.main_window.results olist.select(olist[0]) olist.double_click(0) self.assertEquals(run_dialog.call_count, 1) args, kwargs = run_dialog.call_args dialog, store = args self.assertEquals(dialog, PurchaseDetailsDialog) self.assertTrue(store is not None) self.assertEquals(kwargs[u'model'], purchase)
def test_new_product(self, new_store, run_dialog): new_store.return_value = self.store self.clean_domain( [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) purchase.status = PurchaseOrder.ORDER_PENDING api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.NewProduct) run_dialog.assert_called_once_with(ProductEditor, self.store, model=None)
def setup_widgets(self): self.get_toplevel().set_size_request(*self.size) self.notification_label.set_text('') self.notification_label.set_color('black') if api.sysparam(api.get_default_store()).DISABLE_COOKIES: self.remember.hide() self.remember.set_active(False) gtkimage = gtk.Image() gtkimage.set_from_pixbuf(render_logo_pixbuf('login')) self.logo_container.add(gtkimage) self.logo_container.show_all()
def test_finish_order(self, new_store, run_dialog): new_store.return_value = self.store self.clean_domain( [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) purchase = self.create_purchase_order() purchase.add_item(self.create_sellable(), 2) purchase.get_items()[0].quantity_received = 2 purchase.status = PurchaseOrder.ORDER_CONFIRMED purchase.received_quantity = 2 api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.Finish) run_dialog.assert_called_once_with(PurchaseFinishWizard, self.store, purchase)
def test_finish_workorder_dont_confirm(self, new_store, yesno): new_store.return_value = self.store self.clean_domain([WorkOrderItem, WorkOrder]) workorder = self.create_workorder() # Setted WorkOrder status for Work in Progress workorder.status = WorkOrder.STATUS_WORK_IN_PROGRESS api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(MaintenanceApp, u'maintenance') olist = app.results olist.select(olist[0]) self.assertNotSensitive(app, ['Finish']) workorder.add_sellable(self.create_sellable()) # Selecting again will update actions sensitivity olist.select(olist[0]) self.assertSensitive(app, ['Finish']) # Initial status for the order is Opened self.assertEquals(workorder.status, WorkOrder.STATUS_WORK_IN_PROGRESS) self.assertTrue(workorder.can_finish()) with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): # Click the finish order, but dont confirm the change yesno.return_value = False self.activate(app.Finish) yesno.assert_called_once_with( u"This will finish the selected " "order, marking the work as done." " Are you sure?", gtk.RESPONSE_NO, u"Finish order", u"Don't finish") # Status should not be altered. ie, its still in Progress self.assertEquals(workorder.status, WorkOrder.STATUS_WORK_IN_PROGRESS)
def test_new_quote_order(self, new_store, run_dialog, select_result): new_store.return_value = self.store self.clean_domain( [ReceivingOrderItem, ReceivingOrder, PurchaseItem, PurchaseOrder]) quotation = self.create_quotation() quotation.purchase.add_item(self.create_sellable(), 2) quotation.purchase.status = PurchaseOrder.ORDER_PENDING api.sysparam(self.store).update_parameter(u'SMART_LIST_LOADING', u'0') app = self.create_app(PurchaseApp, u'purchase') olist = app.results olist.select(olist[0]) self.store.retval = olist[0] with mock.patch.object(self.store, 'close'): with mock.patch.object(self.store, 'commit'): self.activate(app.Edit) run_dialog.assert_called_once_with(PurchaseWizard, self.store, quotation.purchase, False) select_result.assert_called_once_with(olist[0])
def testLoanReceipt(self): sysparam_ = api.sysparam(self.store) client = self.create_client() address = self.create_address() address.person = client.person loan = self.create_loan(client=client) for i in range(3): self.create_loan_item(loan=loan, quantity=i) sysparam_.update_parameter(u'PRINT_PROMISSORY_NOTE_ON_LOAN', u'0') self._diff_expected(LoanReceipt, 'loan-receipt', loan) sysparam_.update_parameter(u'PRINT_PROMISSORY_NOTE_ON_LOAN', u'1') self._diff_expected(LoanReceipt, 'loan-receipt-with-pn', loan)
def _configure_boleto(self, number, account, agency, **kwargs): bill = PaymentMethod.get_by_name(self.store, u'bill') bank_account = BankAccount(account=bill.destination_account, bank_account=account, bank_branch=agency, bank_number=int(number), store=self.store) for key, value in kwargs.items(): BillOption(store=self.store, bank_account=bank_account, option=unicode(key), value=value) api.sysparam( self.store).BILL_INSTRUCTIONS = u'Primeia linha da instrução'
def __init__(self, window, store=None): self._suggested_client = None self._current_store = None self._trade = None self._trade_infobar = None ShellApp.__init__(self, window, store=store) self._delivery = None self.param = api.sysparam(self.store) self._coupon = None # Cant use self._coupon to verify if there is a sale, since # CONFIRM_SALES_ON_TILL doesnt create a coupon self._sale_started = False self._scale_settings = DeviceSettings.get_scale_settings(self.store)