def run_from_ui(self, ar, **kw): me = ar.get_user() obj = ar.selected_rows[0] ses = rt.modules.clocking.Session(ticket=obj, user=me) ses.full_clean() ses.save() ar.set_response(refresh=True) if dd.is_installed('clocking'): # Sphinx autodoc dd.inject_action( dd.plugins.clocking.ticket_model, start_session=StartTicketSession()) dd.inject_action( dd.plugins.clocking.ticket_model, end_session=EndTicketSession()) class PrintActivityReport(DirectPrintAction): """Print an activity report. Not yet used. This is meant to be used as a list action on Session, but Lino does not yet support list actions with a parameter window. """ select_rows = False
# logger.info("20140426") kw = super(CreateHousehold, self).action_param_defaults(ar, obj, **kw) kw.update(head=obj) return kw def run_from_ui(self, ar, **kw): pv = ar.action_param_values hh = rt.modules.households.Household.create_household( ar, pv.head, pv.partner, pv.type) ar.success( _("Household has been created"), close_window=True, refresh_all=True) ar.goto_instance(hh) dd.inject_action( config.person_model, create_household=CreateHousehold()) class MembersByPerson(Members): required_roles = dd.required(ContactsUser) label = _("Household memberships") master_key = 'person' column_names = 'household role primary start_date end_date *' # auto_fit_column_widths = True # hide_columns = 'id' slave_grid_format = 'summary' @classmethod def get_slave_summary(self, obj, ar): sar = self.request(master_instance=obj)
def get_vat_regime_choices(country=None, vat_id=None): vat_area = VatAreas.get_for_country(country) # print("20190405", vat_area) for r in VatRegimes.get_list_items(): if vat_area is None or r.vat_area is None or r.vat_area == vat_area: if vat_id or not r.needs_vat_id: yield r @dd.chooser() def partner_vat_regime_choices(cls, country, vat_id): return get_vat_regime_choices(country, vat_id) dd.inject_action( 'contacts.Partner',vat_regime_choices=partner_vat_regime_choices) dd.inject_field( 'contacts.Partner', 'vat_id', models.CharField(_("VAT id"), max_length=200, blank=True)) dd.inject_field( 'ledger.Movement', 'vat_regime', VatRegimes.field(blank=True)) dd.inject_field( 'ledger.Movement', 'vat_class', VatClasses.field(blank=True)) dd.inject_field('ledger.Account', 'vat_column', VatColumns.field(blank=True, null=True))
blank=True, null=True, verbose_name=string_concat(invoiceable_label, ' ', _('(object)')))) dd.inject_field( dd.plugins.invoicing.item_model, 'invoiceable', GenericForeignKey( 'invoiceable_type', 'invoiceable_id', verbose_name=invoiceable_label)) # define a custom chooser because we want to see only invoiceable # models when manually selecting an invoiceable_type: @dd.chooser() def invoiceable_type_choices(cls): return ContentType.objects.get_for_models( *rt.models_by_base(Invoiceable)).values() dd.inject_action( dd.plugins.invoicing.item_model, invoiceable_type_choices=invoiceable_type_choices) @dd.receiver(dd.pre_save, sender=dd.plugins.invoicing.item_model) def item_pre_save_handler(sender=None, instance=None, **kwargs): """When the user sets `title` of an automatically generated invoice item to an empty string, then Lino restores the default value for both title and description """ self = instance if self.invoiceable_id and not self.title: lng = self.voucher.get_print_language() # lng = self.voucher.partner.language or dd.get_default_language() with translation.override(lng):
master = 'ledger.Account' @classmethod def get_data_rows(cls, ar, **flt): account = ar.master_instance if account is None: return [] if not account.clearable: return [] flt.update(cleared=False, account=account) # ignore trade_type to avoid overriding account ar.param_values.trade_type = None return super(DebtsByAccount, cls).get_data_rows(ar, **flt) dd.inject_action('ledger.Account', due=dd.ShowSlaveTable(DebtsByAccount)) class DebtsByPartner(ExpectedMovements): master = 'contacts.Partner' #~ column_names = 'due_date debts payments balance' @classmethod def get_dc(cls, ar=None): return DEBIT @classmethod def get_data_rows(cls, ar, **flt): partner = ar.master_instance if partner is None: return []
from lino.api import dd, rt, _ from .mixins import UpdateSummariesByMaster, SlaveSummarized, Summarized class CheckAllSummaries(dd.Action): label = _("Check all summary data") def run_from_ui(self, ar, fix=None): for sm in rt.models_by_base(Summarized, toplevel_only=True): dd.logger.info("Updating summary data for %s ...", sm._meta.verbose_name_plural) sm.check_all_summaries() ar.set_response(refresh=True) dd.inject_action('system.SiteConfig', check_all_summaries=CheckAllSummaries()) @dd.receiver(dd.pre_analyze) def set_summary_actions(sender, **kw): for mm, summary_models in masters_with_summaries().items(): # remove plain Summarizable models who are their own master, so they # have their own check_summaries button. summary_models = [sm for sm in summary_models if sm is not mm] # if issubclass(mm, SimpleSummary): if len(summary_models): mm.define_action( check_summaries=UpdateSummariesByMaster( mm, summary_models))
def get_vat_regime_choices(country=None): vat_area = VatAreas.get_for_country(country) # print("20190405", vat_area) for r in VatRegimes.get_list_items(): if vat_area is None or r.vat_area is None or r.vat_area == vat_area: yield r @dd.chooser() def partner_vat_regime_choices(cls, country): return get_vat_regime_choices(country) dd.inject_action('contacts.Partner', vat_regime_choices=partner_vat_regime_choices) dd.inject_field('contacts.Partner', 'vat_id', models.CharField(_("VAT id"), max_length=200, blank=True)) dd.inject_field('ledger.Movement', 'vat_regime', VatRegimes.field(blank=True)) dd.inject_field('ledger.Movement', 'vat_class', VatClasses.field(blank=True)) # dd.inject_field('ledger.Account', # 'vat_column', # VatColumns.field(blank=True, null=True)) class VatColumnsChecker(Checker): # model = 'system.SiteConfig'
def ok(ar2): checkout_guest(obj, ar) kw.update(refresh=True) ar2.success(**kw) msg = _("%(guest)s leaves after meeting with %(user)s.") % dict( guest=obj.partner, user=obj.user) ar.confirm(ok, msg, _("Are you sure?")) # dd.update_model( # 'cal.Guest', dd.inject_action( 'cal.Guest', checkin=CheckinVisitor(sort_index=100), receive=ReceiveVisitor(sort_index=101), checkout=CheckoutVisitor(sort_index=102)) # @dd.receiver(dd.pre_analyze) # def my_guest_workflows(sender=None, **kw): # Guest = rt.models.cal.Guest # Guest.checkin = CheckinVisitor(sort_index=100) # Guest.receive = ReceiveVisitor(sort_index=101) # Guest.checkout = CheckoutVisitor(sort_index=102) # GuestStates.excused.add_transition( # required_states='invited accepted absent') # GuestStates.absent.add_transition( # required_states='accepted excused')
button_text = ' ⚡ ' # 26A1 # icon_name = 'lightning' def get_action_permission(self, ar, obj, state): me = ar.get_user() if not me.user_type.has_required_roles([SiteAdmin]): if obj != me: return False return super(UpdateWidgets, self).get_action_permission( ar, obj, state) def run_from_ui(self, ar): for obj in ar.selected_rows: update_widgets_for(ar, obj) dd.inject_action('users.User', update_widgets=UpdateWidgets()) @dd.python_2_unicode_compatible class Widget(UserAuthored, Sequenced): """ """ move_action_names = ('move_up', 'move_down') class Meta(object): app_label = 'dashboard' verbose_name = _("Widget") verbose_name_plural = _("Widgets") item_name = models.CharField(_("Resource"), max_length=200)
# icon_name = 'lightning' def get_action_permission(self, ar, obj, state): me = ar.get_user() if not me.user_type.has_required_roles([SiteAdmin]): if obj != me: return False return super(UpdateWidgets, self).get_action_permission(ar, obj, state) def run_from_ui(self, ar): for obj in ar.selected_rows: update_widgets_for(ar, obj) dd.inject_action('users.User', update_widgets=UpdateWidgets()) @dd.python_2_unicode_compatible class Widget(UserAuthored, Sequenced): """ """ move_action_names = ('move_up', 'move_down') class Meta(object): app_label = 'dashboard' verbose_name = _("Widget") verbose_name_plural = _("Widgets") item_name = models.CharField(_("Resource"), max_length=200)
dd.logger.warning("%d statements were NOT imported from %s", failed_statements, filename) self.failed_statements += failed_statements elif dd.plugins.b2c.delete_imported_xml_files: # Delete imported file if there were no errors try: os.remove(filename) except OSError as err: dd.logger.warning("Failed to delete %s : %s", filename, err) else: dd.logger.info("The file %s has been deleted.", filename) else: dd.logger.info("File %s was imported but NOT deleted.", filename) dd.inject_action('system.SiteConfig', import_b2c=ImportStatements()) class Account(dd.Model): class Meta: app_label = 'b2c' abstract = dd.is_abstract_model(__name__, 'Account') verbose_name = _("Imported bank account") verbose_name_plural = _("Imported bank accounts") iban = IBANField(verbose_name=_("IBAN"), unique=True, blank=False) bic = BICField(verbose_name=_("BIC"), blank=True) account_name = models.CharField(_("Account name"), max_length=70, blank=True) owner_name = models.CharField(_("Owner name"), max_length=70, blank=True)
column_names = 'name id address_column *' window_size = (50, 15) params_panel_hidden = True dd.inject_field( 'contacts.Partner', 'invoice_recipient', dd.ForeignKey( 'contacts.Partner', verbose_name=_("Invoicing address"), blank=True, null=True, help_text=_("Redirect to another partner all invoices which " "should go to this partner."))) dd.inject_action( 'contacts.Partner', show_invoice_partners=dd.ShowSlaveTable( PartnersByInvoiceRecipient)) dd.inject_field( 'contacts.Partner', 'paper_type', dd.ForeignKey('sales.PaperType', null=True, blank=True)) # class Channels(dd.ChoiceList): # label = _("Channel") # add = Channels.add_item # add('P', _("Paper"), 'paper') # add('E', _("E-mail"), 'email')
dd.inject_field( dd.plugins.invoicing.item_model, 'invoiceable', GenericForeignKey('invoiceable_type', 'invoiceable_id', verbose_name=invoiceable_label)) # define a custom chooser because we want to see only invoiceable # models when manually selecting an invoiceable_type: @dd.chooser() def invoiceable_type_choices(cls): return ContentType.objects.get_for_models( *rt.models_by_base(Invoiceable)).values() dd.inject_action(dd.plugins.invoicing.item_model, invoiceable_type_choices=invoiceable_type_choices) @dd.receiver(dd.pre_save, sender=dd.plugins.invoicing.item_model) def item_pre_save_handler(sender=None, instance=None, **kwargs): """When the user sets `title` of an automatically generated invoice item to an empty string, then Lino restores the default value for both title and description """ self = instance if self.invoiceable_id and not self.title: lng = self.voucher.get_print_language() # lng = self.voucher.partner.language or dd.get_default_language() with translation.override(lng): self.title = self.invoiceable.get_invoiceable_title(self.voucher)
column_names = 'name id address_column *' window_size = (50, 15) params_panel_hidden = True dd.inject_field( 'contacts.Partner', 'invoice_recipient', dd.ForeignKey('contacts.Partner', verbose_name=_("Invoicing address"), blank=True, null=True, help_text=_("Redirect to another partner all invoices which " "should go to this partner."))) dd.inject_action( 'contacts.Partner', show_invoice_partners=dd.ShowSlaveTable(PartnersByInvoiceRecipient)) dd.inject_field('contacts.Partner', 'paper_type', dd.ForeignKey('sales.PaperType', null=True, blank=True)) # class Channels(dd.ChoiceList): # label = _("Channel") # add = Channels.add_item # add('P', _("Paper"), 'paper') # add('E', _("E-mail"), 'email') class PaperType(BabelNamed): """Which paper (document template) to use when printing an invoice.
class CheckSummaries(dd.Action): """Web UI version of :manage:`checksummaries`. See there.""" label = _("Update all summary data") def run_from_ui(self, ar, fix=None): for mm, summary_models in list(get_summary_models().items()): for sm in summary_models: dd.logger.info("Updating %s ...", sm._meta.verbose_name_plural) for master in sm.get_summary_masters(): sm.update_for_master(master) ar.set_response(refresh=True) dd.inject_action("system.SiteConfig", check_summaries=CheckSummaries()) @dd.receiver(dd.pre_analyze) def set_summary_actions(sender, **kw): """Installs the `update_summaries` action (an instance of :class:`UpdateSummariesByMaster <lino.modlib.summaries.mixins.UpdateSummariesByMaster>`) on every model for which there is at least one Summary """ for mm, summary_models in list(get_summary_models().items()): mm.define_action(update_summaries=UpdateSummariesByMaster(mm, summary_models)) def get_summary_models():
mail.spam = True mail.full_clean() mail.save() if mails: logger.info("got {} from mailbox: {}".format(mails,mb)) class DeleteSpam(dd.Action): show_in_bbar = True readonly = False # required_roles = dd.login_required(Worker) label = u"X" def run_from_ui(self, ar, **kw): spams = rt.models.django_mailbox.Message.objects.filter(spam = True) logger.info("Deleting spam messages [%s]", spams) def ok(ar): for obj in spams: obj.delete() ar.set_response(refresh=True) ar.confirm( ok, _("Delete {} messages.").format(spams.count()), _("Are you sure?")) dd.inject_action("django_mailbox.Message", delete_spam=DeleteSpam())
def ok(ar2): checkout_guest(obj, ar) kw.update(refresh=True) ar2.success(**kw) msg = _("%(guest)s leaves after meeting with %(user)s.") % dict( guest=obj.partner, user=obj.user) ar.confirm(ok, msg, _("Are you sure?")) # dd.update_model( # 'cal.Guest', dd.inject_action('cal.Guest', checkin=CheckinVisitor(sort_index=100), receive=ReceiveVisitor(sort_index=101), checkout=CheckoutVisitor(sort_index=102)) # @dd.receiver(dd.pre_analyze) # def my_guest_workflows(sender=None, **kw): # Guest = rt.models.cal.Guest # Guest.checkin = CheckinVisitor(sort_index=100) # Guest.receive = ReceiveVisitor(sort_index=101) # Guest.checkout = CheckoutVisitor(sort_index=102) # GuestStates.excused.add_transition( # required_states='invited accepted absent') # GuestStates.absent.add_transition( # required_states='accepted excused') # GuestStates.present.add_transition(
class DebtsByAccount(ExpectedMovements): master = 'accounts.Account' @classmethod def get_data_rows(cls, ar, **flt): account = ar.master_instance if account is None: return [] if not account.clearable: return [] flt.update(cleared=False, account=account) # ignore trade_type to avoid overriding account ar.param_values.trade_type = None return super(DebtsByAccount, cls).get_data_rows(ar, **flt) dd.inject_action('accounts.Account', due=dd.ShowSlaveTable(DebtsByAccount)) class DebtsByPartner(ExpectedMovements): master = 'contacts.Partner' #~ column_names = 'due_date debts payments balance' @classmethod def get_dc(cls, ar=None): return CREDIT @classmethod def get_data_rows(cls, ar, **flt): partner = ar.master_instance if partner is None: return []
paper_type """, window_size=(40, 'auto')) class PartnersByInvoiceRecipient(SalesRules): help_text = _("Show partners having this as invoice recipient.") details_of_master_template = _("%(master)s used as invoice recipient") button_text = "♚" # 265A master_key = 'invoice_recipient' column_names = "partner partner__id partner__address_column *" window_size = (80, 20) dd.inject_action( 'contacts.Partner', show_invoice_partners=dd.ShowSlaveTable(PartnersByInvoiceRecipient)) class Tariff(BabelDesignated): class Meta(object): app_label = 'invoicing' abstract = dd.is_abstract_model(__name__, 'Tariff') verbose_name = _("Flatrate") verbose_name_plural = _("Flatrates") # allow_cascaded_delete = 'product' # product = dd.OneToOneField('products.Product', primary_key=True) number_of_events = models.IntegerField(
invoice_recipient paper_type """, window_size=(40, 'auto')) class PartnersByInvoiceRecipient(SalesRules): help_text = _("Show partners having this as invoice recipient.") details_of_master_template = _("%(master)s used as invoice recipient") button_text = "♚" # 265A master_key = 'invoice_recipient' column_names = "partner partner__id partner__address_column *" window_size = (80, 20) dd.inject_action( 'contacts.Partner', show_invoice_partners=dd.ShowSlaveTable( PartnersByInvoiceRecipient)) class Tariff(BabelDesignated): class Meta(object): app_label = 'invoicing' abstract = dd.is_abstract_model(__name__, 'Tariff') verbose_name = _("Flatrate") verbose_name_plural = _("Flatrates") # allow_cascaded_delete = 'product' # product = dd.OneToOneField('products.Product', primary_key=True)
# logger.info("20140426") kw = super(CreateHousehold, self).action_param_defaults(ar, obj, **kw) kw.update(head=obj) return kw def run_from_ui(self, ar, **kw): pv = ar.action_param_values rt.models.households.Household.create_household( ar, pv.head, pv.partner, pv.type) ar.success( _("Household has been created"), close_window=True, refresh_all=True) # ar.goto_instance(hh) dd.inject_action( config.person_model, create_household=CreateHousehold()) class MembersByPerson(Members): required_roles = dd.login_required(ContactsUser) label = _("Household memberships") master_key = 'person' column_names = 'household role primary start_date end_date *' insert_layout = """ person role household primary """ # auto_fit_column_widths = True
"%d statements were NOT imported from %s", failed_statements, filename) self.failed_statements += failed_statements elif dd.plugins.b2c.delete_imported_xml_files: # Delete imported file if there were no errors try: os.remove(filename) except OSError as err: dd.logger.warning("Failed to delete %s : %s", filename, err) else: dd.logger.info("The file %s has been deleted.", filename) else: dd.logger.info("File %s was imported but NOT deleted.", filename) dd.inject_action('system.SiteConfig', import_b2c=ImportStatements()) @dd.python_2_unicode_compatible class Account(dd.Model): """A bank account related to a given :class:`Partner <lino.modlib.models.contacts.Partner>`. One partner can have more than one bank account. .. attribute:: account_name Name of the account, as assigned by the account servicing institution, in agreement with the account owner in order to provide an additional means of identification of the account. Usage: The account name is different from the