Esempio n. 1
0
    def fields(self):
        # Only users with admin or purchase permission can modify transporters
        user = api.get_current_user(self.store)
        can_modify_transporter = any((
            user.profile.check_app_permission(u'admin'),
            user.profile.check_app_permission(u'purchase'),
        ))
        freight_types = [(v, k) for k, v in Delivery.freights.items()]

        return collections.OrderedDict(
            client=PersonQueryField(_("Client"),
                                    proxy=True,
                                    mandatory=True,
                                    person_type=Client),
            transporter_id=PersonField(_("Transporter"),
                                       proxy=True,
                                       person_type=Transporter,
                                       can_add=can_modify_transporter,
                                       can_edit=can_modify_transporter),
            address=AddressField(_("Address"), proxy=True, mandatory=True),
            freight_type=ChoiceField(_("Freight type"),
                                     proxy=True,
                                     values=freight_types),
            price=PriceField(_("Delivery cost"), proxy=True),
            estimated_fix_date=DateField(_("Estimated delivery date"),
                                         proxy=True),
            volumes_kind=TextField(_("Volumes kind"), proxy=True),
            volumes_quantity=IntegerField(_("Volumes quantity"), proxy=True),
        )
Esempio n. 2
0
class _ItemEditor(BaseEditor):
    model_name = _(u'Work order item')
    model_type = _TempSaleItem
    confirm_widgets = ['price', 'quantity']

    fields = dict(
        price=PriceField(_(u'Price'), proxy=True, mandatory=True),
        quantity=NumericField(_(u'Quantity'), proxy=True, mandatory=True),
    )

    def on_confirm(self):
        self.model.update()

    def on_price__validate(self, widget, value):
        if value <= 0:
            return ValidationError(_(u"The price must be greater than 0"))

        sellable = self.model.sellable
        if not sellable.is_valid_price(value):
            return ValidationError(
                _(u"Max discount for this product "
                  u"is %.2f%%") % sellable.max_discount)

    def on_quantity__validate(self, entry, value):
        sellable = self.model.sellable

        # TODO: Validate quantity properly (checking if the current stock is
        # enougth
        if value <= 0:
            return ValidationError(_(u"The quantity must be greater than 0"))

        if not sellable.is_valid_quantity(value):
            return ValidationError(
                _(u"This product unit (%s) does not "
                  u"support fractions.") % sellable.get_unit_description())
Esempio n. 3
0
 def fields(self):
     return collections.OrderedDict(
         branch_id=PersonField(_('Branch'),
                               proxy=True,
                               person_type=Branch,
                               can_add=False,
                               can_edit=False,
                               mandatory=True),
         method=PaymentMethodField(_('Method'),
                                   payment_type=self.payment_type,
                                   proxy=True,
                                   mandatory=True,
                                   separate=True),
         account=ChoiceField(self.account_label),
         description=TextField(_('Description'), proxy=True,
                               mandatory=True),
         person=PersonQueryField(person_type=self.person_type, proxy=True),
         value=PriceField(_('Value'), proxy=True, mandatory=True),
         due_date=DateField(_('Due date'), proxy=True, mandatory=True),
         category=PaymentCategoryField(_('Category'),
                                       category_type=self.category_type,
                                       proxy=True),
         repeat=ChoiceField(_('Repeat')),
         end_date=DateField(_('End date')),
         attachment=AttachmentField(_('Attachment')))
Esempio n. 4
0
    def fields(self):
        # Only users with admin or purchase permission can modify transporters
        user = api.get_current_user(self.store)
        can_modify_transporter = any((
            user.profile.check_app_permission(u'admin'),
            user.profile.check_app_permission(u'purchase'),
        ))
        freight_types = [(v, k) for k, v in Delivery.freights.items()]
        states = [(v, v) for v in api.get_l10n_field('state').state_list]

        return collections.OrderedDict(
            recipient=PersonQueryField(_("Recipient"), proxy=True, mandatory=True,
                                       person_type=self.person_type),
            transporter_id=PersonField(_("Transporter"), proxy=True,
                                       person_type=Transporter,
                                       can_add=can_modify_transporter,
                                       can_edit=can_modify_transporter),
            address=AddressField(_("Address"), proxy=True, mandatory=True),
            freight_type=ChoiceField(_("Freight type"), proxy=True,
                                     values=freight_types),
            price=PriceField(_("Delivery cost"), proxy=True),
            estimated_fix_date=DateField(_("Estimated delivery date"), proxy=True),
            volumes_kind=TextField(_("Volumes kind"), proxy=True),
            volumes_quantity=IntegerField(_("Volumes quantity"), proxy=True),
            volumes_net_weight=NumericField(_("Volumes net weight"), proxy=True,
                                            digits=3),
            volumes_gross_weight=NumericField(_("Volumes gross weight"),
                                              proxy=True, digits=3),
            vehicle_license_plate=TextField(_("Vehicle license plate"), proxy=True),
            vehicle_state=ChoiceField(_("Vehicle state"), proxy=True, use_entry=True,
                                      values=states),
            vehicle_registration=TextField(_("Vehicle registration"), proxy=True),
        )
Esempio n. 5
0
 def fields(self):
     return collections.OrderedDict(
         name=TextField(_('Name'), mandatory=True, proxy=True),
         budget=PriceField(_('Budget'), mandatory=True, proxy=True),
         description=MultiLineField(_('Description'),
                                    mandatory=True,
                                    proxy=True),
         is_active=BoolField(_('Active'), proxy=True),
     )
Esempio n. 6
0
 def fields(self):
     return collections.OrderedDict(
         code=TextField(_('Code'), proxy=True),
         description=TextField(_('Description'), proxy=True),
         barcode=TextField(_('Barcode'), proxy=True),
         price=PriceField(_('Price'), proxy=True),
         quantity=NumericField(_('Quantity'), proxy=True),
         skip=NumericField(_('Labels to skip'), proxy=True),
     )
Esempio n. 7
0
class CreditEditor(BaseEditor):
    model_type = Payment
    model_name = _('Credit Transaction')

    confirm_widgets = ['description', 'value']

    fields = dict(
        description=TextField(_('Description'), proxy=True, mandatory=True),
        value=PriceField(_('Value'), proxy=True, mandatory=True),
    )

    def __init__(self, store, client, model=None):
        self.client = client
        BaseEditor.__init__(self, store, model)

    def create_model(self, store):
        group = PaymentGroup()
        method = PaymentMethod.get_by_name(store, u'credit')
        branch = api.get_current_branch(store)
        # Set status to PENDING now, to avoid calling set_pending on
        # on_confirm for payments that shoud not have its status changed.
        return Payment(open_date=localtoday(),
                       branch=branch,
                       status=Payment.STATUS_PENDING,
                       description=u'',
                       value=currency(0),
                       base_value=currency(0),
                       due_date=None,
                       method=method,
                       group=group,
                       till=None,
                       category=None,
                       payment_type=Payment.TYPE_OUT,
                       bill_received=False)

    def setup_proxies(self):
        self.add_proxy(self.model, CreditEditor.proxy_widgets)

    def validate_confirm(self):
        return bool(self.model.description and self.model.value)

    def on_confirm(self):
        if self.model.value < 0:
            self.model.payment_type = Payment.TYPE_IN
            self.model.value = abs(self.model.value)
        self.model.base_value = self.model.value
        self.model.due_date = localtoday()
        self.model.group.payer = self.client.person
        self.model.pay()

    def on_value__validate(self, widget, newvalue):
        if newvalue is None or newvalue == 0:
            return ValidationError(_('Value must be different from zero.'))
Esempio n. 8
0
    def fields(self):
        # Only users with admin or purchase permission can modify transporters
        user = api.get_current_user(self.store)
        can_modify_transporter = any((
            user.profile.check_app_permission(u'admin'),
            user.profile.check_app_permission(u'purchase'),
        ))

        return collections.OrderedDict(
            client=PersonQueryField(_("Client"), proxy=True, mandatory=True,
                                    person_type=Client),
            transporter_id=PersonField(_("Transporter"), proxy=True,
                                       person_type=Transporter,
                                       can_add=can_modify_transporter,
                                       can_edit=can_modify_transporter),
            address=AddressField(_("Address"), proxy=True, mandatory=True),
            price=PriceField(_("Delivery cost"), proxy=True),
            estimated_fix_date=DateField(_("Estimated delivery date"), proxy=True),
        )
Esempio n. 9
0
class CostCenterEditor(BaseEditor):
    model_name = _('Cost Center')
    size = (300, -1)
    model_type = CostCenter

    fields = dict(
        name=TextField(_('Name'), mandatory=True, proxy=True),
        budget=PriceField(_('Budget'), mandatory=True, proxy=True),
        description=MultiLineField(_('Description'),
                                   mandatory=True,
                                   proxy=True),
        is_active=BoolField(_('Active'), proxy=True),
    )

    #
    # BaseEditor Hooks
    #

    def create_model(self, store):
        return CostCenter(store=store)
Esempio n. 10
0
class _WorkOrderItemEditor(BaseEditor):
    model_name = _(u'Work order item')
    model_type = WorkOrderItem
    confirm_widgets = ['price', 'quantity']

    fields = dict(
        price=PriceField(_(u'Price'), proxy=True, mandatory=True),
        quantity=NumericField(_(u'Quantity'), proxy=True, mandatory=True),
    )

    def on_price__validate(self, widget, value):
        if value <= 0:
            return ValidationError(_(u"The price must be greater than 0"))

        sellable = self.model.sellable
        # FIXME: Because of the design of the editor, the client
        # could not be set yet.
        category = self.model.order.client and self.model.order.client.category
        if not sellable.is_valid_price(value, category):
            return ValidationError(
                _(u"Max discount for this product "
                  u"is %.2f%%") % sellable.max_discount)

    def on_quantity__validate(self, entry, value):
        sellable = self.model.sellable
        storable = sellable.product_storable
        if not storable:
            return

        if value <= 0:
            return ValidationError(_(u"The quantity must be greater than 0"))

        if value > storable.get_balance_for_branch(self.model.order.branch):
            return ValidationError(
                _(u"This quantity is not available in stock"))

        if not sellable.is_valid_quantity(value):
            return ValidationError(
                _(u"This product unit (%s) does not "
                  u"support fractions.") % sellable.get_unit_description())
Esempio n. 11
0
class PrintLabelEditor(BaseEditor):
    """ This editor is used to gather information to print labels for a
    purchase item
    """
    model_type = object
    title = _(u'Print labels')

    fields = dict(
        code=TextField(_('Code'), proxy=True),
        description=TextField(_('Description'), proxy=True),
        barcode=TextField(_('Barcode'), proxy=True),
        price=PriceField(_('Price'), proxy=True),
        quantity=NumericField(_('Quantity'), proxy=True),
        skip=NumericField(_('Labels to skip'), proxy=True),
    )

    def __init__(self, store, sellable, model=None, max_quantity=None,
                 visual_mode=False):
        self.sellable = sellable
        self.max_quantity = max_quantity
        BaseEditor.__init__(self, store, model, visual_mode)
        self._setup_widgets()

    def _setup_widgets(self):
        for i in [self.code, self.description, self.barcode, self.price]:
            i.set_sensitive(False)
        if self.max_quantity:
            self.quantity.update(self.max_quantity)

    #
    # BaseEditor Hooks
    #

    def create_model(self, store):
        sellable = self.sellable
        return Settable(barcode=sellable.barcode, code=sellable.code,
                        description=sellable.description, price=sellable.price,
                        quantity=Decimal('1'), skip=Decimal('0'))
Esempio n. 12
0
    def fields(self):
        # Check if sellable's unit allow fraction to use decimal places
        unit = self._product.sellable.unit
        if unit and unit.allow_fraction:
            quantity_digits = 3
        else:
            quantity_digits = 0

        fields = collections.OrderedDict(
            quantity=NumericField(_('Quantity'),
                                  proxy=True,
                                  mandatory=True,
                                  digits=quantity_digits), )
        # When creating an inventory, a reason is necessary
        if self._stock_item:
            fields['reason'] = MultiLineField(_('Reason'),
                                              proxy=True,
                                              mandatory=True)
        else:
            # Inventories dont do anything with the cost yet. Maybe we should
            # fix that
            fields['cost'] = PriceField(_('Cost'), proxy=True, mandatory=True)
        return fields
Esempio n. 13
0
 def fields(self):
     return collections.OrderedDict(
         description=TextField(_('Description'), proxy=True, mandatory=True),
         value=PriceField(_('Value'), proxy=True, mandatory=True),
     )
Esempio n. 14
0
 def fields(self):
     return collections.OrderedDict(
         price=PriceField(_(u'Price'), proxy=True, mandatory=True),
         quantity=NumericField(_(u'Quantity'), proxy=True, mandatory=True),
         quantity_reserved=NumericField(_(u'Reserved quantity')),
     )
Esempio n. 15
0
class _WorkOrderItemEditor(BaseEditor):
    model_name = _(u'Work order item')
    model_type = WorkOrderItem
    confirm_widgets = ['price', 'quantity']

    fields = dict(
        price=PriceField(_(u'Price'), proxy=True, mandatory=True),
        quantity=NumericField(_(u'Quantity'), proxy=True, mandatory=True),
    )

    #: The manager is someone who can allow a bigger discount for a sale item.
    manager = None

    def __init__(self, *args, **kwargs):
        BaseEditor.__init__(self, *args, **kwargs)
        self.price.set_icon_activatable(gtk.ENTRY_ICON_PRIMARY,
                                        activatable=True)

    def on_price__validate(self, widget, value):
        if value <= 0:
            return ValidationError(_(u"The price must be greater than 0"))

        sellable = self.model.sellable
        self.manager = self.manager or api.get_current_user(self.store)

        # FIXME: Because of the design of the editor, the client
        # could not be set yet.
        category = self.model.order.client and self.model.order.client.category
        valid_data = sellable.is_valid_price(value, category, self.manager)
        if not valid_data['is_valid']:
            return ValidationError(
                _(u'Max discount for this product is %.2f%%.' %
                  valid_data['max_discount']))

    def on_price__icon_press(self, entry, icon_pos, event):
        if icon_pos != gtk.ENTRY_ICON_PRIMARY:
            return

        # Ask for the credentials of a different user that can possibly allow a
        # bigger discount.
        self.manager = run_dialog(CredentialsDialog, self, self.store)
        if self.manager:
            self.price.validate(force=True)

    def on_quantity__validate(self, entry, value):
        sellable = self.model.sellable

        if value <= 0:
            return ValidationError(_(u"The quantity must be greater than 0"))

        if not sellable.is_valid_quantity(value):
            return ValidationError(
                _(u"This product unit (%s) does not "
                  u"support fractions.") % sellable.get_unit_description())

        try:
            remaining_quantity = self.model.get_remaining_quantity()
        except StockError:
            # No need to validate the quantity, the item doesn't have a storable
            return

        if value > self.model.quantity + remaining_quantity:
            return ValidationError(
                _(u"This quantity is not available in stock"))
Esempio n. 16
0
class _PaymentEditor(BaseEditor):
    confirm_widgets = ['due_date']
    model_type = Payment
    model_name = _('payment')

    # Override in subclass
    person_type = None
    category_type = None
    payment_type = None

    fields = dict(branch=PersonField(_('Branch'),
                                     proxy=True,
                                     person_type=Branch,
                                     can_add=False,
                                     can_edit=False,
                                     mandatory=True),
                  method=PaymentMethodField(_('Method'),
                                            proxy=True,
                                            mandatory=True,
                                            separate=True),
                  description=TextField(_('Description'),
                                        proxy=True,
                                        mandatory=True),
                  person=PersonField(proxy=True),
                  value=PriceField(_('Value'), proxy=True, mandatory=True),
                  due_date=DateField(_('Due date'), proxy=True,
                                     mandatory=True),
                  category=PaymentCategoryField(_('Category'), proxy=True),
                  repeat=ChoiceField(_('Repeat')),
                  end_date=DateField(_('End date')),
                  attachment=AttachmentField(_('Attachment')))

    def __init__(self, store, model=None, category=None):
        """ A base class for additional payments

        :param store: a store
        :param model: a :class:`stoqlib.domain.payment.payment.Payment` object or None

        """
        self.fields['person'].person_type = self.person_type
        self.fields['category'].category_type = self.category_type
        self.fields['method'].payment_type = self.payment_type

        BaseEditor.__init__(self, store, model)
        self._setup_widgets()
        if category:
            self.category.select_item_by_label(category)
        self.description.grab_focus()

    #
    # BaseEditor hooks
    #

    def create_model(self, store):
        group = PaymentGroup()
        money = PaymentMethod.get_by_name(store, u'money')
        branch = api.get_current_branch(store)
        # Set status to PENDING now, to avoid calling set_pending on
        # on_confirm for payments that shoud not have its status changed.
        return Payment(open_date=localtoday().date(),
                       branch=branch,
                       status=Payment.STATUS_PENDING,
                       description=u'',
                       value=currency(0),
                       base_value=currency(0),
                       due_date=None,
                       method=money,
                       group=group,
                       till=None,
                       category=None,
                       payment_type=self.payment_type,
                       bill_received=False)

    def setup_proxies(self):
        repeat_types = get_interval_type_items(with_multiples=True,
                                               adverb=True)
        repeat_types.insert(0, (_('Once'), _ONCE))
        self.repeat.prefill(repeat_types)
        self.add_proxy(self.model, _PaymentEditor.proxy_widgets)

    def validate_confirm(self):
        if (self.repeat.get_selected() != _ONCE and not self._validate_date()):
            return False
        # FIXME: the kiwi view should export it's state and it should
        #        be used by default
        return bool(self.model.description and self.model.due_date
                    and self.model.value)

    def on_confirm(self):
        self.model.base_value = self.model.value
        person = self.person.get_selected_data()
        if (person is not None and person is not ValueUnset and
                # FIXME: PersonField should never let get_selected_data()
                #        return anything different from None and the model.
                person != ""):
            setattr(self.model.group, self.person_attribute,
                    self.store.fetch(person.person))

        self.model.attachment = self.fields['attachment'].attachment

        self.store.add(self.model.group)
        self.store.add(self.model)

        if self.repeat.get_selected() != _ONCE:
            Payment.create_repeated(self.store, self.model,
                                    self.repeat.get_selected(),
                                    self.model.due_date.date(),
                                    self.end_date.get_date())

    # Private

    def _setup_widgets(self):
        self.person_lbl.set_label(self._person_label)
        if self.model.group.sale:
            label = _("Sale details")
        elif self.model.group.purchase:
            label = _("Purchase details")
        elif self.model.group._renegotiation:
            label = _("Details")
        else:
            label = _("Details")
        self.details_button = self.add_button(label)
        self.details_button.connect('clicked',
                                    self._on_details_button__clicked)

        self.end_date.set_sensitive(False)
        if self.edit_mode:
            for field_name in [
                    'value', 'due_date', 'person', 'repeat', 'end_date',
                    'branch', 'method'
            ]:
                field = self.fields[field_name]
                field.can_add = False
                field.can_edit = False
                field.set_sensitive(False)

        person = getattr(self.model.group, self.person_attribute)
        if person:
            store = person.store
            facet = store.find(self.person_type, person=person).one()
            self.person.select(facet)

    def _show_order_dialog(self):
        group = self.model.group
        if group.sale:
            sale_view = self.store.find(SaleView, id=group.sale.id).one()
            run_dialog(SaleDetailsDialog, self, self.store, sale_view)
        elif group.purchase:
            run_dialog(PurchaseDetailsDialog, self, self.store, group.purchase)
        elif group._renegotiation:
            run_dialog(RenegotiationDetailsDialog, self, self.store,
                       group._renegotiation)
        elif group.stock_decrease:
            run_dialog(StockDecreaseDetailsDialog, self, self.store,
                       group.stock_decrease)
        else:
            run_dialog(LonelyPaymentDetailsDialog, self, self.store,
                       self.model)

    def _get_min_date_for_interval(self, due_date, interval_type):
        if not due_date or interval_type is None:
            return None
        return due_date + interval_type_as_relativedelta(interval_type)

    def _validate_date(self):
        if not self.end_date.props.sensitive:
            return True
        end_date = self.end_date.get_date()
        due_date = self.due_date.get_date()
        min_date = self._get_min_date_for_interval(due_date,
                                                   self.repeat.read())

        if end_date and due_date:
            if end_date < due_date:
                self.end_date.set_invalid(
                    _("End date cannot be before start date"))
            elif min_date and end_date < min_date:
                self.end_date.set_invalid(
                    _("End date must be after %s for this "
                      "repeat interval") % min_date.strftime('%x'))
            else:
                self.end_date.set_valid()
                self.refresh_ok(self.is_valid)
                return True
        elif not end_date:
            self.end_date.set_invalid(_("Date cannot be empty"))
        elif not due_date:
            self.due_date.set_invalid(_("Date cannot be empty"))
        self.refresh_ok(False)
        return False

    def _validate_person(self):
        payment_type = self.payment_type
        method = self.method.get_selected()
        if method.operation.require_person(payment_type):
            self.person.set_property('mandatory', True)
        else:
            self.person.set_property('mandatory', False)

    #
    # Kiwi Callbacks
    #

    def on_value__validate(self, widget, newvalue):
        if newvalue is None or newvalue <= 0:
            return ValidationError(_("The value must be greater than zero."))

    def on_repeat__content_changed(self, repeat):
        if repeat.get_selected() == _ONCE:
            self.end_date.set_sensitive(False)

            # FIXME: need this check so tests won't crash
            if hasattr(self, 'main_dialog'):
                self.refresh_ok(True)

            return

        self.end_date.set_sensitive(True)
        self._validate_date()

    def on_due_date__content_changed(self, due_date):
        self._validate_date()

    def on_end_date__content_changed(self, end_date):
        self._validate_date()

    def _on_details_button__clicked(self, widget):
        self._show_order_dialog()

    def on_method__content_changed(self, method):
        self.person.validate(force=True)
        self._validate_person()
Esempio n. 17
0
class CreditEditor(BaseEditor):
    model_type = Settable
    model_name = _('Credit Transaction')

    confirm_widgets = ['description', 'value']

    fields = dict(
        description=TextField(_('Description'), proxy=True, mandatory=True),
        value=PriceField(_('Value'), proxy=True, mandatory=True),
    )

    def __init__(self, store, client, model=None):
        self.client = store.fetch(client)
        BaseEditor.__init__(self, store, model)

    def create_model(self, store):
        return Settable(description=u'', value=currency(0))

    def _create_payment(self):
        group = PaymentGroup()
        group.payer = self.client.person

        method = PaymentMethod.get_by_name(self.store, u'credit')
        branch = api.get_current_branch(self.store)

        if self.model.value < 0:
            payment_type = Payment.TYPE_IN
        else:
            payment_type = Payment.TYPE_OUT

        # Set status to PENDING now, to avoid calling set_pending on
        # on_confirm for payments that shoud not have its status changed.
        payment = Payment(open_date=localtoday(),
                          branch=branch,
                          status=Payment.STATUS_PENDING,
                          description=self.model.description,
                          value=abs(self.model.value),
                          base_value=abs(self.model.value),
                          due_date=localtoday(),
                          method=method,
                          group=group,
                          till=None,
                          category=None,
                          payment_type=payment_type,
                          bill_received=False)
        payment.pay()

        return payment

    def validate_confirm(self):
        return bool(self.model.description and
                    self.model.value)

    def on_confirm(self):
        self.retval = self._create_payment()

    def on_value__validate(self, widget, newvalue):
        if newvalue == 0:
            return ValidationError(_(u'Value must be different from zero.'))
        if self.client.credit_account_balance + newvalue < 0:
            return ValidationError(_(u'Client credit cannot be negative.'))