Exemplo n.º 1
0
    def test_create(self):
        # Allow creating purchases in the past.
        sysparam.set_bool(self.store, 'ALLOW_OUTDATED_OPERATIONS', True)

        self.wizard = PurchaseWizard(self.store)
        purchase_branch = self.create_branch()
        purchase_order = PurchaseOrder(branch=purchase_branch)
        sellable = self.create_sellable()
        purchase_order.add_item(sellable=sellable)
        self.wizard.model.identifier = 12345
        self.wizard.model.open_date = localdate(2010, 1, 3).date()
        self._check_start_step('wizard-purchase-start-step')
        self._check_item_step('wizard-purchase-item-step')
        self._check_payment_step('wizard-purchase-payment-step')

        purchase = self.wizard.model
        models = [purchase]
        models.extend(purchase.get_items())
        models.extend(purchase.payments)
        models.append(purchase.group)

        self.check_wizard(self.wizard, 'wizard-purchase-finish-step',
                          models=models)

        self.click(self.wizard.next_button)
Exemplo n.º 2
0
    def test_create(self):
        # Allow creating purchases in the past.
        sysparam(self.store).update_parameter(u"ALLOW_OUTDATED_OPERATIONS",
                                              u"1")

        self.wizard = PurchaseWizard(self.store)
        purchase_branch = self.create_branch()
        purchase_order = PurchaseOrder(branch=purchase_branch)
        sellable = self.create_sellable()
        purchase_order.add_item(sellable=sellable)
        self.wizard.model.identifier = 12345
        self.wizard.model.open_date = localdate(2010, 1, 3).date()
        self._check_start_step('wizard-purchase-start-step')
        self._check_item_step('wizard-purchase-item-step')
        self._check_payment_step('wizard-purchase-payment-step')

        purchase = self.wizard.model
        models = [purchase]
        models.extend(purchase.get_items())
        models.extend(purchase.payments)
        models.append(purchase.group)

        self.check_wizard(self.wizard,
                          'wizard-purchase-finish-step',
                          models=models)

        self.click(self.wizard.next_button)
Exemplo n.º 3
0
    def test_create(self):
        # Allow creating purchases in the past.
        sysparam.set_bool(self.store, 'ALLOW_OUTDATED_OPERATIONS', True)

        with self.sysparam(MANDATORY_CHECK_NUMBER=True):
            self.wizard = PurchaseWizard(self.store)
            purchase_branch = self.create_branch()
            purchase_order = PurchaseOrder(branch=purchase_branch,
                                           station=self.current_station,
                                           store=self.store)
            sellable = self.create_sellable()
            purchase_order.add_item(sellable=sellable)
            self.wizard.model.identifier = 12345
            self.wizard.model.open_date = localdate(2010, 1, 3).date()
            self._check_start_step('wizard-purchase-start-step')
            self._check_item_step('wizard-purchase-item-step')
            payment_step = self.wizard.get_current_step()
            payment_step.slave.bank_first_check_number.set_text('12')
            self._check_payment_step('wizard-purchase-payment-step')

            purchase = self.wizard.model
            models = [purchase]
            models.extend(purchase.get_items())
            models.extend(purchase.payments)
            models.append(purchase.group)

            self.check_wizard(self.wizard,
                              'wizard-purchase-finish-step',
                              models=models)

            self.click(self.wizard.next_button)
Exemplo n.º 4
0
    def _create_purchase_order(self, store, supplier, items):
        order = PurchaseOrder(supplier=store.fetch(supplier),
                              branch=api.get_current_branch(store),
                              status=PurchaseOrder.ORDER_QUOTING,
                              expected_receival_date=None,
                              responsible=api.get_current_user(store),
                              group=PaymentGroup(store=store),
                              store=store)

        for sellable, quantity in items:
            order.add_item(store.fetch(sellable), quantity)

        return order
Exemplo n.º 5
0
    def _create_purchase_order(self, store, supplier, items):
        order = PurchaseOrder(supplier=store.fetch(supplier),
                              branch=api.get_current_branch(store),
                              status=PurchaseOrder.ORDER_QUOTING,
                              expected_receival_date=None,
                              responsible=api.get_current_user(store),
                              group=PaymentGroup(store=store),
                              store=store)

        for sellable, quantity in items:
            order.add_item(store.fetch(sellable), quantity)

        return order
Exemplo n.º 6
0
 def next_step(self):
     self.wizard.all_products = self.all_products.get_active()
     if self.wizard.is_for_another_branch():
         info(_('The identifier for this purchase will be defined when it '
                'is synchronized to the detination branch'))
         self.model.identifier = PurchaseOrder.get_temporary_identifier(self.store)
     return PurchaseItemStep(self.wizard, self, self.store, self.model)
Exemplo n.º 7
0
    def _on_WorkOrderStatusChangedEvent(self, order, old_status):
        if old_status == WorkOrder.STATUS_OPENED:
            #Do nothing at this point.
            return

        optical_wo = OpticalWorkOrder.find_by_work_order(order.store, order)
        # If there is no optical WO, nothing to do here
        if optical_wo is None:
            return

        if optical_wo.can_create_purchase():
            with api.new_store() as store:
                rv = run_dialog(OpticalSupplierEditor, None, store, order)
            if not rv:
                # Return None to let the status be changed without creating a purchase order
                return

            order.supplier_order = rv.supplier_order
            optical_wo.create_purchase(order.store.fetch(rv.supplier),
                                       order.store.fetch(rv.item),
                                       rv.is_freebie)
            return

        for purchase in PurchaseOrder.find_by_work_order(order.store, order):
            if optical_wo.can_receive_purchase(purchase):
                optical_wo.receive_purchase(purchase, reserve=True)
Exemplo n.º 8
0
 def _create_and_confirm_purchase_order(self, identifier, payment_group,
                                        notes, station, responsible):
     self.purchase_order = PurchaseOrder(
         store=self.store,
         identifier=identifier,
         branch=self.branch,
         status=PurchaseOrder.ORDER_PENDING,
         open_date=localnow(),
         notes=notes,
         freight_type=self.freight_type,
         expected_freight=self.freight_cost,
         supplier=self.nfe_supplier.supplier,
         group=payment_group,
         station=station)
     self._add_purchase_order_item()
     self.purchase_order.confirm(responsible=responsible)
Exemplo n.º 9
0
    def _on_WorkOrderStatusChangedEvent(self, order, old_status):
        if old_status == WorkOrder.STATUS_OPENED:
            #Do nothing at this point.
            return

        optical_wo = OpticalWorkOrder.find_by_work_order(order.store, order)
        # If there is no optical WO, nothing to do here
        if optical_wo is None:
            return

        if optical_wo.can_create_purchase():
            with api.new_store() as store:
                rv = run_dialog(OpticalSupplierEditor, None, store, order)
            if not rv:
                # Return None to let the status be changed without creating a purchase order
                return

            order.supplier_order = rv.supplier_order
            optical_wo.create_purchase(order.store.fetch(rv.supplier),
                                       order.store.fetch(rv.item),
                                       rv.is_freebie)
            return

        for purchase in PurchaseOrder.find_by_work_order(order.store, order):
            if optical_wo.can_receive_purchase(purchase):
                optical_wo.receive_purchase(purchase, reserve=True)
Exemplo n.º 10
0
    def __init__(self, store, model=None, edit_mode=False):
        title = self._get_title(model)
        self.sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE')
        self.current_branch = api.get_current_branch(store)
        if self.sync_mode and not model:
            self.temporary_identifier = PurchaseOrder.get_temporary_identifier(
                store)

        model = model or self._create_model(store)
        # Should we show all products or only the ones associated with the
        # selected supplier?
        self.all_products = False

        # If we receive the order right after the purchase.
        self.receiving_model = None
        purchase_edit = [
            PurchaseOrder.ORDER_CONFIRMED, PurchaseOrder.ORDER_PENDING
        ]

        if not model.status in purchase_edit:
            raise ValueError('Invalid order status. It should '
                             'be ORDER_PENDING or ORDER_CONFIRMED')
        first_step = StartPurchaseStep(self, store, model)
        BaseWizard.__init__(self,
                            store,
                            first_step,
                            model,
                            title=title,
                            edit_mode=edit_mode)
Exemplo n.º 11
0
    def test_find_by_work_order(self):
        work_order = self.create_workorder()
        purchase = self.create_purchase_order()
        purchase.work_order = work_order

        results = PurchaseOrder.find_by_work_order(work_order.store, work_order)
        for expected_purchase in results:
            self.assertEquals(purchase, expected_purchase)
Exemplo n.º 12
0
    def test_find_by_work_order(self):
        work_order = self.create_workorder()
        purchase = self.create_purchase_order()
        purchase.work_order = work_order

        results = PurchaseOrder.find_by_work_order(work_order.store, work_order)
        for expected_purchase in results:
            self.assertEquals(purchase, expected_purchase)
Exemplo n.º 13
0
 def create_purchase_order(self, supplier=None, branch=None):
     from stoqlib.domain.purchase import PurchaseOrder
     group = self.create_payment_group()
     return PurchaseOrder(supplier=supplier or self.create_supplier(),
                          branch=branch or self.create_branch(),
                          group=group,
                          responsible=get_current_user(self.store),
                          store=self.store)
Exemplo n.º 14
0
 def receive_purchase(self,
                      purchase_order: PurchaseOrder,
                      station: BranchStation,
                      user: LoginUser,
                      reserve=False):
     receiving = purchase_order.create_receiving_order(station)
     receiving.confirm(user)
     if reserve:
         self.reserve_products(purchase_order, user)
Exemplo n.º 15
0
 def _create_model(self, store):
     supplier = sysparam(store).SUGGESTED_SUPPLIER
     branch = api.get_current_branch(store)
     status = PurchaseOrder.ORDER_QUOTING
     group = PaymentGroup(store=store)
     return PurchaseOrder(supplier=supplier, branch=branch, status=status,
                          expected_receival_date=None,
                          responsible=api.get_current_user(store),
                          group=group,
                          store=store)
Exemplo n.º 16
0
    def _dialog_purchase(self, id):
        from stoqlib.domain.purchase import PurchaseOrder
        from stoqlib.gui.dialogs.purchasedetails import PurchaseDetailsDialog

        store = api.new_store()
        purchase = PurchaseOrder.get(int(id), store)
        retval = run_dialog(PurchaseDetailsDialog, self.app, store, purchase)
        if store.confirm(retval):
            self.refresh()
        store.close()
Exemplo n.º 17
0
    def test_new_purchase_confirm(self, run_dialog, new_store):
        new_store.return_value = self.store

        supplier = self.create_supplier()
        sale = self.create_sale()
        product = self.create_product()
        work_order = self.create_workorder()
        work_order.status = WorkOrder.STATUS_WORK_IN_PROGRESS
        work_order.sale = sale
        work_item = work_order.add_sellable(product.sellable)
        self.create_optical_work_order(work_order)
        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == work_order:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)

        # Before the action, there are no purchase orders for this work order
        results = PurchaseOrder.find_by_work_order(self.store, work_order)
        self.assertEquals(results.count(), 0)

        action = OpticalWorkOrderActions.get_instance().get_action('OpticalNewPurchase')
        run_dialog.return_value = Settable(supplier=supplier,
                                           supplier_order='1111',
                                           item=work_item,
                                           is_freebie=True)
        with contextlib.nested(
                mock.patch.object(self.store, 'commit'),
                mock.patch.object(self.store, 'close')):
            self.activate(action)

        run_dialog.assert_called_once_with(OpticalSupplierEditor, None,
                                           self.store, work_order)

        # Now there should be one purchase order
        results = PurchaseOrder.find_by_work_order(self.store, work_order)
        self.assertEquals(results.count(), 1)
        app.deactivate()
Exemplo n.º 18
0
    def test_new_purchase_confirm(self, run_dialog, new_store):
        new_store.return_value = self.store

        supplier = self.create_supplier()
        sale = self.create_sale()
        product = self.create_product()
        work_order = self.create_workorder()
        work_order.status = WorkOrder.STATUS_WORK_IN_PROGRESS
        work_order.sale = sale
        work_item = work_order.add_sellable(product.sellable)
        self.create_optical_work_order(work_order)
        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == work_order:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)

        # Before the action, there are no purchase orders for this work order
        results = PurchaseOrder.find_by_work_order(self.store, work_order)
        self.assertEquals(results.count(), 0)

        action = OpticalWorkOrderActions.get_instance().get_action('OpticalNewPurchase')
        run_dialog.return_value = Settable(supplier=supplier,
                                           supplier_order='1111',
                                           item=work_item,
                                           is_freebie=True)
        with contextlib.nested(
                mock.patch.object(self.store, 'commit'),
                mock.patch.object(self.store, 'close')):
            self.activate(action)

        run_dialog.assert_called_once_with(OpticalSupplierEditor, None,
                                           self.store, work_order)

        # Now there should be one purchase order
        results = PurchaseOrder.find_by_work_order(self.store, work_order)
        self.assertEquals(results.count(), 1)
        app.deactivate()
Exemplo n.º 19
0
 def _create_model(self, store):
     supplier_id = sysparam.get_object_id('SUGGESTED_SUPPLIER')
     branch = api.get_current_branch(store)
     group = PaymentGroup(store=store)
     status = PurchaseOrder.ORDER_PENDING
     return PurchaseOrder(supplier_id=supplier_id,
                          responsible=api.get_current_user(store),
                          branch=branch,
                          status=status,
                          group=group,
                          store=store)
Exemplo n.º 20
0
    def create_purchase(self, supplier, work_order_item, is_freebie):
        """Create a purchase

        :param supplier: the |supplier| of that purchase
        :param work_order_item: The work order item that a purchase is being created
        for.
        :param is_freebie: indicates if the item is a freebie
        """
        sellable = work_order_item.sellable
        store = self.work_order.store
        purchase = PurchaseOrder(store=store,
                                 status=PurchaseOrder.ORDER_PENDING,
                                 supplier=supplier,
                                 responsible=api.get_current_user(store),
                                 branch=api.get_current_branch(store),
                                 work_order=self.work_order)
        if is_freebie:
            purchase.notes = _('The product %s is a freebie') % sellable.description
            # FIXME We may want the cost 0, but as it is we wont be able to
            # receive this purchase without changing the receiving. We must
            # evaluate the consequences of changing the receiving a little bit
            # further in order to change that behavior.
            cost = decimal.Decimal('0.01')
        else:
            cost = sellable.cost

        # Add the sellable to the purchase
        purchase_item = purchase.add_item(sellable,
                                          quantity=work_order_item.quantity,
                                          cost=cost)
        work_order_item.purchase_item = purchase_item

        purchase.confirm()
        return purchase
Exemplo n.º 21
0
    def _get_purchase_from_quote(self, quote, store):
        quote_purchase = quote.purchase
        real_order = quote_purchase.clone()
        has_selected_items = False
        # add selected items
        for quoted_item in self.quoted_items:
            order = store.fetch(quoted_item.order)
            if order is quote_purchase and quoted_item.selected:
                purchase_item = store.fetch(quoted_item.item).clone()
                purchase_item.order = real_order
                has_selected_items = True

        # override some cloned data
        real_order.group = PaymentGroup(store=store)
        real_order.open_date = localtoday().date()
        real_order.quote_deadline = None
        real_order.status = PurchaseOrder.ORDER_PENDING

        if has_selected_items:
            return real_order
        else:
            PurchaseOrder.delete(real_order.id, store=store)
Exemplo n.º 22
0
    def _get_purchase_from_quote(self, quote, store):
        quote_purchase = quote.purchase
        real_order = quote_purchase.clone()
        has_selected_items = False
        # add selected items
        for quoted_item in self.quoted_items:
            order = store.fetch(quoted_item.order)
            if order is quote_purchase and quoted_item.selected:
                purchase_item = store.fetch(quoted_item.item).clone()
                purchase_item.order = real_order
                has_selected_items = True

        # override some cloned data
        real_order.group = PaymentGroup(store=store)
        real_order.open_date = localtoday().date()
        real_order.quote_deadline = None
        real_order.status = PurchaseOrder.ORDER_PENDING

        if has_selected_items:
            return real_order
        else:
            PurchaseOrder.delete(real_order.id, store=store)
Exemplo n.º 23
0
    def create_purchase(self, supplier, work_order_item, is_freebie):
        """Create a purchase

        :param supplier: the |supplier| of that purchase
        :param work_order_item: The work order item that a purchase is being created
        for.
        :param is_freebie: indicates if the item is a freebie
        """
        sellable = work_order_item.sellable
        store = self.work_order.store
        current_branch = api.get_current_branch(store)
        purchase = PurchaseOrder(store=store,
                                 status=PurchaseOrder.ORDER_PENDING,
                                 supplier=supplier,
                                 responsible=api.get_current_user(store),
                                 branch=current_branch,
                                 work_order=self.work_order)
        if is_freebie:
            purchase.notes = _('The product %s is a freebie') % sellable.description
            # FIXME We may want the cost 0, but as it is we wont be able to
            # receive this purchase without changing the receiving. We must
            # evaluate the consequences of changing the receiving a little bit
            # further in order to change that behavior.
            cost = decimal.Decimal('0.01')
        else:
            psi = ProductSupplierInfo.find_by_product_supplier(store, sellable.product,
                                                               supplier)
            cost = psi.base_cost if psi else sellable.cost

        # Add the sellable to the purchase
        purchase_item = purchase.add_item(sellable,
                                          quantity=work_order_item.quantity,
                                          cost=cost)
        work_order_item.purchase_item = purchase_item

        purchase.confirm()
        return purchase
Exemplo n.º 24
0
    def create_purchase_order(self,
                              responsible,
                              create_payments=False,
                              station_name=u'StoqLinkServer'):
        payment_group = self._create_payment_group()
        identifier = PurchaseOrder.get_temporary_identifier(self.store)
        notes = _(u"Invoice number: %s") % self.invoice_number
        station = set_current_branch_station(self.store,
                                             station_name,
                                             confirm=False)
        self._create_and_confirm_purchase_order(identifier, payment_group,
                                                notes, station, responsible)
        if create_payments:
            self._create_payments(station)

        self.create_receiving_order(station)
        self.store.commit()

        return self.purchase_order
Exemplo n.º 25
0
    def test_work_order_cancel_change_status(self):
        product = self.create_product()
        opt_type = OpticalProduct.TYPE_GLASS_LENSES
        optical_product = self.create_optical_product(optical_type=opt_type)
        optical_product.product = product
        sale = self.create_sale()
        sale_item = sale.add_sellable(sellable=product.sellable)
        wo = self.create_workorder()
        work_item = wo.add_sellable(product.sellable)
        work_item.sale_item = sale_item
        wo.sale = sale
        wo.approve(self.current_user)

        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == wo:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)

        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            # No optical work order related to this WO, the dialog doesn't even run
            wo.work(self.current_branch, self.current_user)
            self.assertNotCalled(run_dialog)

        wo.pause(self.current_user, 'Reason')
        optical_wo = self.create_optical_work_order()
        optical_wo.work_order = wo

        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            run_dialog.return_value = None
            wo.work(self.current_branch, self.current_user)
            # At this point we didnt create a purchase
            results = PurchaseOrder.find_by_work_order(wo.store, wo)
            self.assertEquals(len(list(results)), 0)
        app.deactivate()
Exemplo n.º 26
0
    def test_work_order_cancel_change_status(self):
        product = self.create_product()
        opt_type = OpticalProduct.TYPE_GLASS_LENSES
        optical_product = self.create_optical_product(optical_type=opt_type)
        optical_product.product = product
        sale = self.create_sale()
        sale_item = sale.add_sellable(sellable=product.sellable)
        wo = self.create_workorder()
        work_item = wo.add_sellable(product.sellable)
        work_item.sale_item = sale_item
        wo.sale = sale
        wo.approve()

        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == wo:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)

        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            # No optical work order related to this WO, the dialog doesn't even run
            wo.work()
            self.assertNotCalled(run_dialog)

        wo.pause('Reason')
        optical_wo = self.create_optical_work_order()
        optical_wo.work_order = wo

        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            run_dialog.return_value = None
            wo.work()
            # At this point we didnt create a purchase
            results = PurchaseOrder.find_by_work_order(wo.store, wo)
            self.assertEquals(len(list(results)), 0)
        app.deactivate()
Exemplo n.º 27
0
    def __init__(self, store, model=None, edit_mode=False):
        title = self._get_title(model)
        self.sync_mode = api.sysparam.get_bool('SYNCHRONIZED_MODE')
        self.current_branch = api.get_current_branch(store)
        if self.sync_mode and not model:
            self.temporary_identifier = PurchaseOrder.get_temporary_identifier(store)

        model = model or self._create_model(store)
        # Should we show all products or only the ones associated with the
        # selected supplier?
        self.all_products = False

        # If we receive the order right after the purchase.
        self.receiving_model = None
        purchase_edit = [PurchaseOrder.ORDER_CONFIRMED,
                         PurchaseOrder.ORDER_PENDING]

        if not model.status in purchase_edit:
            raise ValueError('Invalid order status. It should '
                             'be ORDER_PENDING or ORDER_CONFIRMED')
        first_step = StartPurchaseStep(self, store, model)
        BaseWizard.__init__(self, store, first_step, model, title=title,
                            edit_mode=edit_mode)
Exemplo n.º 28
0
    def test_work_order_change_status(self):
        supplier = self.create_supplier()
        product = self.create_product()
        opt_type = OpticalProduct.TYPE_GLASS_LENSES
        optical_product = self.create_optical_product(optical_type=opt_type)
        optical_product.product = product
        sale = self.create_sale()
        sale_item = sale.add_sellable(sellable=product.sellable)
        wo = self.create_workorder()
        work_item = wo.add_sellable(product.sellable)
        work_item.sale_item = sale_item
        wo.sale = sale
        optical_wo = self.create_optical_work_order()
        optical_wo.work_order = wo

        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == wo:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)
        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            wo.approve(self.current_user)
            run_dialog.return_value = Settable(supplier=supplier,
                                               supplier_order='1111',
                                               item=work_item,
                                               is_freebie=False)
            wo.work(self.current_branch, self.current_user)
            results = PurchaseOrder.find_by_work_order(wo.store, wo)
            self.assertEquals(len(list(results)), 1)

        wo.finish(self.current_branch, self.current_user)
        app.deactivate()
Exemplo n.º 29
0
    def test_work_order_change_status(self):
        supplier = self.create_supplier()
        product = self.create_product()
        opt_type = OpticalProduct.TYPE_GLASS_LENSES
        optical_product = self.create_optical_product(optical_type=opt_type)
        optical_product.product = product
        sale = self.create_sale()
        sale_item = sale.add_sellable(sellable=product.sellable)
        wo = self.create_workorder()
        work_item = wo.add_sellable(product.sellable)
        work_item.sale_item = sale_item
        wo.sale = sale
        optical_wo = self.create_optical_work_order()
        optical_wo.work_order = wo

        app = self.create_app(ServicesApp, u'services')
        app.search.refresh()

        for wo_view in app.search.results:
            if wo_view.work_order == wo:
                break

        self.assertIsNotNone(wo_view)
        app.search.results.select(wo_view)
        with mock.patch('plugins.optical.opticalui.run_dialog') as run_dialog:
            wo.approve()
            run_dialog.return_value = Settable(supplier=supplier,
                                               supplier_order='1111',
                                               item=work_item,
                                               is_freebie=False)
            wo.work()
            results = PurchaseOrder.find_by_work_order(wo.store, wo)
            self.assertEquals(len(list(results)), 1)

        wo.finish()
        app.deactivate()
Exemplo n.º 30
0
    def process_one(self, data, fields, store):
        person = store.find(Person, name=data.supplier_name).one()
        if person is None or person.supplier is None:
            raise ValueError(u"%s is not a valid supplier" % (
                data.supplier_name, ))
        supplier = person.supplier

        person = store.find(Person, name=data.transporter_name).one()
        if person is None or person.transporter is None:
            raise ValueError(u"%s is not a valid transporter" % (
                data.transporter_name, ))
        transporter = person.transporter

        person = store.find(Person, name=data.branch_name).one()
        if person is None or person.branch is None:
            raise ValueError(u"%s is not a valid branch" % (
                data.branch_name, ))
        branch = person.branch

        person = store.find(Person, name=data.user_name).one()
        if person is None or person.login_user is None:
            raise ValueError(u"%s is not a valid user" % (
                data.user_name, ))
        login_user = person.login_user

        group = PaymentGroup(store=store)
        purchase = PurchaseOrder(store=store,
                                 status=PurchaseOrder.ORDER_PENDING,
                                 supplier=supplier,
                                 transporter=transporter,
                                 group=group,
                                 responsible=get_current_user(store),
                                 branch=branch)

        for sellable in self.parse_multi(Sellable, data.sellable_list, store):
            if not sellable.product:
                continue
            PurchaseItem(store=store,
                         quantity=int(data.quantity),
                         base_cost=sellable.cost,
                         sellable=sellable,
                         order=purchase)

        method = PaymentMethod.get_by_name(store, data.payment_method)
        method.create_payment(Payment.TYPE_OUT, purchase.group, branch,
                              purchase.purchase_total,
                              self.parse_date(data.due_date))
        purchase.confirm()

        receiving_order = ReceivingOrder(responsible=login_user,
                                         supplier=supplier,
                                         invoice_number=int(data.invoice),
                                         transporter=transporter,
                                         branch=branch,
                                         store=store)
        receiving_order.add_purchase(purchase)

        for purchase_item in purchase.get_items():
            ReceivingOrderItem(
                store=store,
                cost=purchase_item.sellable.cost,
                sellable=purchase_item.sellable,
                quantity=int(data.quantity),
                purchase_item=purchase_item,
                receiving_order=receiving_order
            )
        receiving_order.confirm()
Exemplo n.º 31
0
    def process_one(self, data, fields, store):
        person = store.find(Person, name=data.supplier_name).one()
        if person is None or person.supplier is None:
            raise ValueError(u"%s is not a valid supplier" %
                             (data.supplier_name, ))
        supplier = person.supplier

        person = store.find(Person, name=data.transporter_name).one()
        if person is None or person.transporter is None:
            raise ValueError(u"%s is not a valid transporter" %
                             (data.transporter_name, ))
        transporter = person.transporter

        person = store.find(Person, name=data.branch_name).one()
        if person is None or person.branch is None:
            raise ValueError(u"%s is not a valid branch" %
                             (data.branch_name, ))
        branch = person.branch

        login_user = store.find(LoginUser, username=u'admin').one()
        group = PaymentGroup(store=store)
        purchase = PurchaseOrder(store=store,
                                 status=PurchaseOrder.ORDER_PENDING,
                                 open_date=self.parse_date(data.due_date),
                                 supplier=supplier,
                                 transporter=transporter,
                                 group=group,
                                 responsible=get_current_user(store),
                                 branch=branch)

        for sellable in self.parse_multi(Sellable, data.sellable_list, store):
            if not sellable.product:
                continue
            PurchaseItem(store=store,
                         quantity=int(data.quantity),
                         base_cost=sellable.cost,
                         sellable=sellable,
                         order=purchase)

        method = PaymentMethod.get_by_name(store, data.payment_method)
        method.create_payment(Payment.TYPE_OUT, purchase.group, branch,
                              purchase.purchase_total,
                              self.parse_date(data.due_date))
        purchase.confirm()
        for payment in purchase.payments:
            payment.open_date = purchase.open_date

        receiving_order = ReceivingOrder(responsible=login_user,
                                         supplier=supplier,
                                         invoice_number=int(data.invoice),
                                         transporter=transporter,
                                         branch=branch,
                                         store=store)
        receiving_order.add_purchase(purchase)

        for purchase_item in purchase.get_items():
            ReceivingOrderItem(store=store,
                               cost=purchase_item.sellable.cost,
                               sellable=purchase_item.sellable,
                               quantity=int(data.quantity),
                               purchase_item=purchase_item,
                               receiving_order=receiving_order)
        receiving_order.confirm()
Exemplo n.º 32
0
class NFePurchase(Domain):
    __storm_table__ = 'nfe_purchase'

    user_id = IdCol()

    #: The user responsible for the import
    user = Reference(user_id, "LoginUser.id")
    branch_id = IdCol()

    #: The branch that is buying/receiving the products
    branch = Reference(branch_id, "Branch.id")

    nfe_supplier_id = IdCol()

    #: The supplier of the products
    nfe_supplier = Reference(nfe_supplier_id, "NFeSupplier.id")

    purchase_order_id = IdCol()

    #: Reference the purchase order when the importing is done
    purchase_order = Reference(purchase_order_id, "PurchaseOrder.id")

    #: The CNPJ of the branch that is importing the nfe
    cnpj = UnicodeCol(default=u"")

    #: Invoice number
    invoice_number = IntCol()

    #: Invoice series
    invoice_series = IntCol()

    #: Stores the date that this nfe was imported
    process_date = DateTimeCol(default_factory=localnow)

    #: If this purchase is already confirmed
    confirm_purchase = BoolCol(default=False)

    #: Freight type can be FOB and CIF
    freight_type = UnicodeCol(default=u"fob")

    #: The price of the freight
    freight_cost = PriceCol()

    #: The total cost of products + services
    total_cost = PriceCol()

    #: The Raw NFe's XML
    xml = XmlCol()

    payments = ReferenceSet('id', 'NFePayment.nfe_purchase_id')

    @property
    def supplier_name(self):
        return self.nfe_supplier.name or self.nfe_supplier.fancy_name

    @property
    def branch_description(self):
        return self.branch.get_description()

    @property
    def freight_type_str(self):
        if self.freight_type == PurchaseOrder.FREIGHT_FOB:
            return u"FOB"
        return u"CIF"

    @property
    def items(self):
        items = self.store.find(NFeItem, NFeItem.nfe_purchase == self)
        return items

    @classmethod
    def find_purchase_order(cls, store, nfe_supplier, invoice_number,
                            invoice_series):
        return store.find(
            NFePurchase,
            And(NFePurchase.nfe_supplier == nfe_supplier,
                NFePurchase.invoice_number == invoice_number,
                NFePurchase.invoice_series == invoice_series)).one()

    # Private Methods

    def _create_payment_group(self):
        return PaymentGroup(store=self.store,
                            recipient=self.nfe_supplier.supplier.person,
                            payer=self.branch.person)

    def _create_and_confirm_purchase_order(self, identifier, payment_group,
                                           notes, station, responsible):
        self.purchase_order = PurchaseOrder(
            store=self.store,
            identifier=identifier,
            branch=self.branch,
            status=PurchaseOrder.ORDER_PENDING,
            open_date=localnow(),
            notes=notes,
            freight_type=self.freight_type,
            expected_freight=self.freight_cost,
            supplier=self.nfe_supplier.supplier,
            group=payment_group,
            station=station)
        self._add_purchase_order_item()
        self.purchase_order.confirm(responsible=responsible)

    def _add_purchase_order_item(self):
        for item in self.items:
            sellable = item.sellable
            purchase_item = self.purchase_order.add_item(
                sellable=sellable,
                quantity=item.quantity,
                cost=item.cost,
                ipi_value=item.ipi_cost,
                icms_st_value=item.icmsst_cost)

            item.purchase_item_id = purchase_item.id
            sellable.product.ncm = item.ncm or sellable.product.ncm
            self.maybe_create_product_supplier_info(item,
                                                    self.nfe_supplier.supplier)

            product = sellable.product
            if product and product.is_package:
                for component in product.get_components():
                    self.purchase_order.add_item(
                        sellable=component.component.sellable,
                        # The real cost and quantity will be
                        # calculated from the parent item
                        cost=item.cost,
                        quantity=item.quantity,
                        parent=purchase_item)

    def _create_payments(self, station):
        nfe_payments = list(self.payments)
        # FIXME: receive from frontend
        method = PaymentMethod.get_by_name(store=self.store, name=u"bill")

        # FIXME: Select method in frontend and add option to split the payment
        # in more than one duplicate
        identifier = Payment.get_temporary_identifier(self.store)
        if not nfe_payments:
            payment = method.create_payment(
                branch=self.purchase_order.branch,
                station=station,
                payment_type=Payment.TYPE_OUT,
                payment_group=self.purchase_order.group,
                value=self.purchase_order.purchase_total,
                identifier=identifier)
            payment.status = u'paid'
            return payment

        payments = []
        for i, item in enumerate(nfe_payments, start=1):
            identifier = Payment.get_temporary_identifier(self.store)
            payment = Payment(store=self.store,
                              branch=self.purchase_order.branch,
                              identifier=identifier,
                              value=item.value,
                              base_value=item.value,
                              due_date=item.due_date,
                              status=Payment.STATUS_PAID,
                              group=self.purchase_order.group,
                              method=method,
                              bill_received=True,
                              payment_type=Payment.TYPE_OUT,
                              station=station)
            payment.description = method.describe_payment(
                payment.group, i, len(list(nfe_payments)))
            item.description = payment.description
            self.purchase_order.group.add_item(payment)
            payments.append(payment)

        return payments

    #
    # Public
    #

    def get_key(self):
        if self.xml is None:
            return

        inf_nfe = self.xml.find('.//{*}infNFe')
        # Removing prefix NFe from the actual Id
        key = inf_nfe.get('Id')[3:]
        return key

    def find_or_create_supplier(self, nfe_supplier):
        # FIXME: Need to do the same thing to Individual suppliers
        person = Person.get_or_create_by_document(
            self.store,
            nfe_supplier.cnpj,
            name=nfe_supplier.name,
            phone_number=nfe_supplier.phone_number,
            notes=u"Automatically created by Stoq-Link")

        person.company.state_registry = nfe_supplier.state_registry
        person.company.fancy_name = nfe_supplier.fancy_name or nfe_supplier.name

        if person.supplier is None:
            supplier = Supplier(store=self.store, person=person)
            nfe_supplier.supplier = supplier

        return person.supplier

    def create_purchase_order(self,
                              responsible,
                              create_payments=False,
                              station_name=u'StoqLinkServer'):
        payment_group = self._create_payment_group()
        identifier = PurchaseOrder.get_temporary_identifier(self.store)
        notes = _(u"Invoice number: %s") % self.invoice_number
        station = set_current_branch_station(self.store,
                                             station_name,
                                             confirm=False)
        self._create_and_confirm_purchase_order(identifier, payment_group,
                                                notes, station, responsible)
        if create_payments:
            self._create_payments(station)

        self.create_receiving_order(station)
        self.store.commit()

        return self.purchase_order

    def create_receiving_order(self, station):
        notes = u"Created automatically with Stoq-Link"
        # TODO Eventually get this from the invoice data.
        cfop = sysparam.get_object(self.store, 'DEFAULT_RECEIVING_CFOP')
        receiving_invoice = ReceivingInvoice(
            store=self.store,
            freight_total=self.freight_cost,
            invoice_number=self.invoice_number,
            invoice_total=self.total_cost,
            supplier=self.purchase_order.supplier,
            branch=self.branch,
            responsible=self.user,
            station=station)

        receiving_order = ReceivingOrder(store=self.store,
                                         branch=self.branch,
                                         station=station,
                                         notes=notes,
                                         cfop=cfop,
                                         confirm_date=datetime.datetime.now(),
                                         status=u'closed',
                                         receiving_invoice=receiving_invoice)

        receiving_order.add_purchase(self.purchase_order)
        for item in self.purchase_order.get_items():
            receiving_order.add_purchase_item(item=item)

        if self.freight_type == PurchaseOrder.FREIGHT_CIF:
            receiving_order.update_payments(create_freight_payment=True)

        receiving_invoice.freight_type = receiving_invoice.guess_freight_type()
        receiving_order.confirm(self.user)

        return receiving_order

    def maybe_create_product_supplier_info(self, nfe_item, supplier):
        from stoqlib.domain.product import ProductSupplierInfo
        product = nfe_item.sellable.product
        info = product.get_product_supplier_info(supplier, self.branch)

        if not info:
            info = ProductSupplierInfo(store=self.store,
                                       product=nfe_item.sellable.product,
                                       supplier_code=nfe_item.supplier_code,
                                       supplier=supplier,
                                       branch=self.branch)

        info.base_cost = Decimal(nfe_item.cost)
        extra_cost = nfe_item.ipi_cost + nfe_item.icmsst_cost
        nfe_item.sellable.cost = info.base_cost + extra_cost

    def create_sellable(self, product_info, responsible):
        if product_info.get('is_package') != 'true':
            raise SellableError(
                """A criação de produtos somente é permitida para produtos do tipo pacote.
                Verifique o cache do seu navegador.""")

        sellable = None
        if product_info["code"]:
            sellable = self.store.find(Sellable,
                                       Sellable.code == product_info["code"])
        if sellable:
            return

        sellable = Sellable(store=self.store,
                            description=product_info["description"],
                            cost=Decimal(product_info["cost"]),
                            price=Decimal(product_info["price"]))

        sellable.code = product_info["code"]
        sellable.barcode = product_info["barcode"]
        sellable.notes = "Created via API" + product_info["notes"]
        sellable.unit_id = product_info["unit_id"] or None
        sellable.tax_constant_id = product_info["tax_constant"] or None
        sellable.default_sale_cfop_id = product_info[
            "default_sale_cfop_id"] or None
        sellable.category_id = product_info["category_id"] or None
        # FIXME Need to get more info from NFe to fill both Product and Storable
        product = Product(store=self.store, sellable=sellable)
        product.manage_stock = product_info.get('manage_stock') == 'true'
        product.is_package = product_info.get('is_package') == 'true'
        package_quantity = product_info.get('package_quantity')
        item_ean = product_info.get('item_ean')
        item = self.store.find(Sellable, barcode=item_ean).one()
        ProductComponent(product=product,
                         component=item.product,
                         price=sellable.get_price(),
                         quantity=Decimal(package_quantity))
        return sellable