def add_fields(self, form, index): """that adds the field in, overwriting the previous default field""" super(MissionStaffingInlineFormset, self).add_fields(form, index) if self.instance.start_date: minDate = self.instance.start_date.replace(day=1) else: minDate = self.instance.staffing_start_date() if minDate: minDate = max(minDate, date.today() - timedelta(365)) minDate = min(minDate, date.today()) else: minDate = None if self.instance.end_date: maxDate = self.instance.end_date.replace(day=1) else: maxDate = None form.fields["consultant"] = ModelChoiceField( widget=ConsultantChoices(attrs={ 'data-placeholder': _("Select a consultant to add forecast...") }), queryset=Consultant.objects) form.fields["staffing_date"] = StaffingDateChoicesField( minDate=minDate, maxDate=maxDate) form.fields["charge"].widget.attrs.setdefault("size", 3) # Reduce default size form.fields["comment"].widget.attrs.setdefault("class", "hidden-xs hidden-sm")
class CompanyForm(PydiciCrispyModelForm): class Meta: model = Company businessOwner = ConsultantChoices(label=_("Business Owner")) def __init__(self, *args, **kwargs): super(CompanyForm, self).__init__(*args, **kwargs) self.helper.layout = Layout(Div(Column("name", "code", "businessOwner", "web", css_class="col-md-6"), Column(css_class="col-md-6"), css_class="row"), self.submit)
def add_fields(self, form, index): """that adds the field in, overwriting the previous default field""" super(MissionStaffingInlineFormset, self).add_fields(form, index) minDate = self.instance.staffing_set.all().aggregate(Min("staffing_date")).values() if minDate and minDate[0]: minDate = min(minDate[0], date.today()) else: minDate = None form.fields["consultant"] = ConsultantChoices(label=_("Consultant"), widget=AutoHeavySelect2Widget(select2_options={"dropdownAutoWidth": "true", "placeholder": _("Select a consultant to add forecast...")})) form.fields["staffing_date"] = StaffingDateChoices(widget=Select2Widget(select2_options={"placeholder": _("Select a month...")}), minDate=minDate) form.fields["charge"].widget.attrs.setdefault("size", 3) # Reduce default size
class MissionForm(PydiciCrispyModelForm): """Form used to change mission name and price""" contacts = MissionContactMChoices(required=False) lead = LeadChoices(required=False) responsible = ConsultantChoices(required=False) def __init__(self, *args, **kwargs): super(MissionForm, self).__init__(*args, **kwargs) self.helper.layout = Layout(Div(Column(Field("description", placeholder=_("Name of this mission. Leave blank when leads has only one mission")), AppendedText("price", "k€"), "billing_mode", "probability", "nature", "active", css_class="col-md-6"), Column(Field("deal_id", placeholder=_("Leave blank to auto generate")), "subsidiary", "responsible", "contacts", css_class="col-md-6"), css_class="row"), Field("lead", type="hidden"), Field("archived_date", type="hidden"), self.submit) def clean_price(self): """Ensure mission price don't exceed remaining lead amount""" if not self.cleaned_data["price"]: # Don't check anything if not price given return self.cleaned_data["price"] if not self.instance.lead: raise ValidationError(_("Cannot add price to mission without lead")) if not self.instance.lead.sales: raise ValidationError(_("Mission's lead has no sales price. Define lead sales price.")) total = 0 # Total price for all missions except current one for mission in self.instance.lead.mission_set.exclude(id=self.instance.id): if mission.price: total += mission.price remaining = self.instance.lead.sales - total if self.cleaned_data["price"] > remaining: raise ValidationError(_(u"Only %s k€ are remaining on this lead. Define a lower price" % remaining)) # No error, we return data as is return self.cleaned_data["price"] class Meta: model = Mission
class LeadForm(PydiciCrispyModelForm): class Meta: model = Lead responsible = ConsultantChoices(required=False, label=_("Responsible")) salesman = SalesManChoices(required=False, label=_("Salesman")) business_broker = BusinessBrokerChoices(required=False, label=_("Business broker")) paying_authority = BusinessBrokerChoices(required=False, label=_("Paying authority")) client = ClientChoices() staffing = ConsultantMChoices(required=False) tags = TagField(label="", required=False) def __init__(self, *args, **kwargs): super(LeadForm, self).__init__(*args, **kwargs) self.helper.layout = Layout( TabHolder( Tab( _("Identification"), Field( "name", placeholder=mark_safe( _("Name of the lead. don't include client name"))), AppendedText( "client", "<a href='%s' target='_blank'><span class='glyphicon glyphicon-plus'></span></a>" % reverse("crm.views.client")), "subsidiary", "description", Field("action", placeholder=_("Next commercial action to be done"))), Tab( _("State and tracking"), Div( Column( "responsible", Field("due_date", placeholder=_("Due date for next step"), css_class="datepicker"), Field( "start_date", placeholder=_("Date of the operational start"), css_class="datepicker"), css_class='col-md-6'), Column(Field( "deal_id", placeholder=_("Leave blank to auto generate")), Field( "client_deal_id", placeholder=_("Internal client reference")), "state", css_class='col-md-6'))), Tab( _("Commercial"), Div( Column(AppendedText("sales", "k€"), "salesman", css_class='col-md-6'), Column(AppendedText( "business_broker", "<a href='%s' target='_blank'><span class='glyphicon glyphicon-plus'></span></a>" % reverse("businessbroker_add"), placeholder=_( "If the leads was brought by a third party")), AppendedText( "paying_authority", "<a href='%s' target='_blank'><span class='glyphicon glyphicon-plus'></span></a>" % reverse("businessbroker_add"), placeholder=_( "If payment is done by a third party")), css_class='col-md-6'))), Tab( _("Staffing"), Div(Field( "staffing", placeholder=_("People that could contribute...")), Field( "external_staffing", placeholder= _("People outside company that could contribute..." )), css_class="col-md-6"))), Fieldset("", "send_email"), Field("creation_date", type="hidden"), Field("tags", css_class="hide" ), # Don't use type=hidden, it breaks tag parsing. self.submit) def clean_sales(self): """Ensure sale amount is defined at lead when commercial proposition has been sent""" if self.cleaned_data["sales"] or self.data["state"] in ( 'QUALIF', 'WRITE_OFFER', 'SLEEPING', 'LOST', 'FORGIVEN'): # Sales is defined or we are in early step, nothing to say return self.cleaned_data["sales"] else: # We can't tolerate that sale amount is not known at this step of the process raise ValidationError( _("Sales amount must be defined at this step of the commercial process" )) def clean_deal_id(self): """Ensure deal id is unique. Cannot be done at database level because we tolerate null/blank value and all db engines are not consistent in the way they handle that. SQL ISO is really fuzzy about that. Sad""" if not self.cleaned_data["deal_id"]: # No value, no pb :-) return self.cleaned_data["deal_id"] else: if Lead.objects.filter( deal_id=self.cleaned_data["deal_id"]).exclude( id=self.instance.id).exists(): raise ValidationError( _("Deal id must be unique. Use another value or let the field blank for automatic computation" )) else: return self.cleaned_data["deal_id"]