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), )
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())
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')))
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), )
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), )
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), )
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.'))
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), )
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)
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())
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'))
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
def fields(self): return collections.OrderedDict( description=TextField(_('Description'), proxy=True, mandatory=True), value=PriceField(_('Value'), proxy=True, mandatory=True), )
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')), )
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"))
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()
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.'))