class CreditNoteRelatedForm(base.CremeForm):
    credit_notes = MultiCreatorEntityField(label=_('Credit notes'),
                                           model=CreditNote)

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.billing_document = entity
        existing = Relation.objects.filter(
            subject_entity=entity.id,
            type=constants.REL_OBJ_CREDIT_NOTE_APPLIED)

        # TODO waiting for automated change of status when a credit note is out of date by looking to expiration date
        # TODO Add another filter today <= expiration_date ??
        q_filter = ~Q(pk__in=[rel.object_entity_id for rel in existing]) & \
                    Q(currency=entity.currency.id,
                      # status=CreditNoteStatus.objects.get(pk=ISSUED_CREDIT_NOTE).id, # TODO workflow status
                      relations__type=constants.REL_SUB_BILL_RECEIVED,
                      relations__object_entity=entity.get_real_entity().get_target().id,
                     )

        self.fields['credit_notes'].q_filter = q_filter

    def save(self):
        create_relation = partial(
            Relation.objects.safe_create,
            subject_entity=self.billing_document,
            type_id=constants.REL_OBJ_CREDIT_NOTE_APPLIED,
            user=self.user,
        )

        for entity in self.cleaned_data['credit_notes']:
            create_relation(object_entity=entity)
Esempio n. 2
0
class CampaignAddListForm(CremeForm):
    messaging_lists = MultiCreatorEntityField(label=_('Lists'), required=False, model=MessagingList)

    # error_messages = {
    #     'already_linked': _('Following lists are already related to this campaign: %(lists)s'),
    # }

    blocks = FieldBlockManager(('general', _('Messaging lists'), '*'))

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.campaign = entity
        self.fields['messaging_lists'].q_filter = ~Q(
            id__in=[*entity.lists.values_list('id', flat=True)],
        )

    # # In fact duplicate is not a problem with django's m2m
    # def clean_lists(self):
    #     messaging_lists = self.cleaned_data['messaging_lists']
    #     current_lists   = frozenset(self.campaign.lists.values_list('pk', flat=True))
    #     duplicate       = [mlist for mlist in messaging_lists if mlist.id in current_lists]
    #
    #     if duplicate:
    #         raise ValidationError(
    #             self.error_messages['already_linked'],
    #             params={'lists': ', '.join(mlist.name for mlist in duplicate)},
    #             code='already_linked',
    #         )
    #
    #     return messaging_lists

    def save(self):
        add_mlist = self.campaign.lists.add
        for mlist in self.cleaned_data['messaging_lists']:
            add_mlist(mlist)
Esempio n. 3
0
class ProductLineMultipleAddForm(_LineMultipleAddForm):
    items = MultiCreatorEntityField(label=_('Products'),
                                    model=products.get_product_model())

    blocks = core_forms.FieldBlockManager(
        ('general', _('Products choice'), ['items']),
        ('additional',
         _('Optional global information applied to your selected products'),
         ['quantity', 'vat', 'discount_value']))

    def _get_line_class(self):
        return ProductLine
Esempio n. 4
0
class AddOrganisationsForm(CremeForm):  # TODO: factorise
    recipients = MultiCreatorEntityField(
        label=_('Organisations'),
        required=False,
        model=Organisation,
    )  # other filter (name + email)??

    blocks = FieldBlockManager(('general', _('Organisations recipients'), '*'))

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ml = entity

    def save(self):
        organisations = self.ml.organisations

        # TODO: check if email if ok ????
        for organisation in self.cleaned_data['recipients']:
            organisations.add(organisation)
Esempio n. 5
0
class AddContactsForm(CremeForm):
    recipients = MultiCreatorEntityField(
        label=_('Contacts'),
        required=False,
        model=Contact,
    )  # other filter (name + email)??

    blocks = FieldBlockManager(('general', _('Contacts recipients'), '*'))

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ml = entity

    def save(self):
        contacts = self.ml.contacts

        # TODO: check if email if ok ????
        for contact in self.cleaned_data['recipients']:
            contacts.add(contact)
Esempio n. 6
0
class CampaignAddListForm(CremeForm):
    messaging_lists = MultiCreatorEntityField(
        label=_('Lists'), required=False, model=MessagingList,
    )

    blocks = FieldBlockManager({
        'id': 'general', 'label': _('Messaging lists'), 'fields': '*',
    })

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.campaign = entity
        self.fields['messaging_lists'].q_filter = ~Q(
            id__in=[*entity.lists.values_list('id', flat=True)],
        )

    def save(self):
        add_mlist = self.campaign.lists.add
        for mlist in self.cleaned_data['messaging_lists']:
            add_mlist(mlist)
Esempio n. 7
0
class AddContactsForm(CremeForm):
    # TODO: other filter (name + email) ?
    recipients = MultiCreatorEntityField(
        label=_('Contacts'), required=False, model=Contact,
    )

    blocks = FieldBlockManager({
        'id': 'general', 'label': _('Contacts recipients'), 'fields': '*',
    })

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.messaging_list = entity

    def save(self):
        contacts = self.messaging_list.contacts

        # TODO: check if email if ok ????
        for contact in self.cleaned_data['recipients']:
            contacts.add(contact)
Esempio n. 8
0
class ServiceLineMultipleAddForm(_LineMultipleAddForm):
    items = MultiCreatorEntityField(label=_('Services'),
                                    model=products.get_service_model())

    blocks = core_forms.FieldBlockManager(
        {
            'id': 'general',
            'label': _('Services choice'),
            'fields': ['items'],
        },
        {
            'id':
            'additional',
            'label':
            _('Optional global information applied to your selected services'),
            'fields': ['quantity', 'vat', 'discount_value'],
        },
    )

    def _get_line_class(self):
        return ServiceLine
Esempio n. 9
0
class EntityEmailForm(base_forms.CremeModelForm):
    """Mails are related to the selected contacts/organisations & the 'current' entity.
    Mails are send to selected contacts/organisations.
    """
    sender = EmailField(label=_('Sender'))

    c_recipients = MultiCreatorEntityField(label=_('Contacts'),
                                           required=False,
                                           model=Contact,
                                           q_filter={'email__gt': ''})
    o_recipients = MultiCreatorEntityField(label=_('Organisations'),
                                           required=False,
                                           model=Organisation,
                                           q_filter={'email__gt': ''})

    send_me = BooleanField(label=_('Send me a copy of this mail'),
                           required=False)

    error_messages = {
        'no_person': _('Select at least a Contact or an Organisation'),
    }

    blocks = base_forms.FieldBlockManager(
        ('recipients', _('Who'),
         ['user', 'sender', 'send_me', 'c_recipients', 'o_recipients']),
        ('content', _('What'), ['subject', 'body', 'body_html']),
        ('extra', _('With'), ['signature', 'attachments']),
    )

    class Meta:
        model = EntityEmail
        fields = ('user', 'sender', 'subject', 'body', 'body_html',
                  'signature', 'attachments')

    def __init__(self, entity, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.entity = entity

        if isinstance(entity, (Contact, Organisation)):
            fn, msg = ('c_recipients', _('Beware: the contact «{}» has no email address!')) \
                      if isinstance(entity, Contact) else \
                      ('o_recipients', _('Beware: the organisation «{}» has no email address!'))
            field = self.fields[fn]

            if entity.email:
                field.initial = [entity.pk]
            else:
                field.help_text = msg.format(entity)

        self.user_contact = contact = self.user.linked_contact

        if contact.email:
            self.fields['sender'].initial = contact.email

        def finalize_recipient_field(name, model):
            if FieldsConfig.get_4_model(model).is_fieldname_hidden('email'):
                self.fields[name] = CharField(
                    label=self.fields[name].label,
                    required=False,
                    widget=Label,
                    initial=gettext(
                        'Beware: the field «Email address» is hidden ;'
                        ' please contact your administrator.'),
                )

        finalize_recipient_field('c_recipients', Contact)
        finalize_recipient_field('o_recipients', Organisation)

    def _clean_recipients(self, field_name):
        if isinstance(self.fields[field_name].widget, Label):
            return []

        recipients = self.cleaned_data.get(field_name) or []
        bad_entities = []

        for entity in recipients:
            try:
                validate_email(entity.email)
            except ValidationError:
                bad_entities.append(entity)

        if bad_entities:
            msg_format = gettext('The email address for {} is invalid')
            user = self.user

            for entity in bad_entities:
                self.add_error(field_name,
                               msg_format.format(entity.allowed_str(user)))

        return recipients

    def clean_c_recipients(self):
        return self._clean_recipients('c_recipients')

    def clean_o_recipients(self):
        return self._clean_recipients('o_recipients')

    def clean(self):
        cdata = super().clean()

        if not self._errors and not cdata['c_recipients'] and not cdata[
                'o_recipients']:
            raise ValidationError(self.error_messages['no_person'],
                                  code='no_person')

        return cdata

    def save(self):
        cdata = self.cleaned_data
        get_data = cdata.get

        sender = get_data('sender')
        subject = get_data('subject')
        body = get_data('body')
        body_html = get_data('body_html')
        signature = get_data('signature')
        attachments = get_data('attachments')
        user = get_data('user')

        sending_error = False

        def create_n_send_mail(recipient_address):
            nonlocal sending_error

            email = EntityEmail.create_n_send_mail(
                sender=sender,
                recipient=recipient_address,
                subject=subject,
                user=user,
                body=body,
                body_html=body_html,
                signature=signature,
                attachments=attachments,
            )

            if email.status == MAIL_STATUS_SENDINGERROR:
                sending_error = True

            return email

        with atomic():
            if get_data('send_me'):
                create_n_send_mail(sender)

            user_contact = self.user_contact
            create_relation = partial(Relation.objects.create, user=user)

            for recipient in chain(cdata['c_recipients'],
                                   cdata['o_recipients']):
                email = create_n_send_mail(recipient.email)

                create_relation(subject_entity=email,
                                type_id=REL_SUB_MAIL_SENDED,
                                object_entity=user_contact)
                create_relation(subject_entity=email,
                                type_id=REL_SUB_MAIL_RECEIVED,
                                object_entity=recipient)

        if sending_error:
            entity_emails_send_type.refresh_job()