Optionale Produkte im Angebot

3. Februar 2010 17:56

Hallo Zusammen,

wir stehen gerade vor dem Problem, das wir des öffteren Optionanle Produkte im Angebot haben.
Unser Momentaner Ansatz sieht wie folgt aus:

In der Angebotsposition gibt es ein neues Feld "Optional" mit den Werten "Ja/Nein"
So weit so einfach und vll. auch nicht schlecht :-)

Jetzt kam aber die Anforderung, das die Gesamtpreisberechungen Optionale Produkte auslassen soll.

Sprich ich biete Kaffeemaschine XYZ an mit Menge 1 und Preis von 50.
Kaffeemaschine ABC Optional mit Menge 1 und Preis von 75.
Der Angebotsgesamtpreis soll jetzt 50 sein und nicht 125

Wie würd ich das normalerweise umsetzen? Bis jetzt hat unser Entwickler noch keinen Anhaltspunkt gefunden, wann und wo der in die Preisberechung von CRM eingreifen kann.

Alternativen sind auch willkommen...

Danke für die Hilfe
Pascal

Re: Optionale Produkte im Angebot

3. Februar 2010 18:02

Hallo Pascal,

das geht nur über ein Plugin. In diesem gibt es das Pre-Image mit den Daten vom öffnen des Datensatzes und das Post-Image mit den Daten direkt vor dem Speichern. Euer Entwickler muss nur auf das Update des Angebotes reagieren, die Werte neu berechnen und dem Post-Image zuweisen.

Re: Optionale Produkte im Angebot

4. Februar 2010 16:17

Hallo Michael,

das scheint alles irgendwie nicht zu funktionieren.

das ist der aktuelle Code

Code:
public void Execute(IPluginExecutionContext context)
        {
            // Verify we have an entity to work with
            if (context.InputParameters.Properties.Contains("Target") &&
                context.InputParameters.Properties["Target"] is DynamicEntity && context.Depth<2)
            {
                using (ICrmService service = context.CreateCrmService(true))
                {
                    // Obtain the target business entity from the input parmameters.
                    DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];
                    decimal val = 37; //((CrmMoney)((((DynamicEntity)(context.PostEntityImages["PostImage"])).Properties["totalamount"]))).Value;
                    if (entity.Properties.Contains("discountamount"))
                        {
                            ((CrmMoney)entity.Properties["discountamount"]).Value = val ;
                        }
                    else
                        {
                            CrmMoneyProperty manualdiscountProperty = new CrmMoneyProperty("discountamount", new CrmMoney(val));
                            entity.Properties.Add(manualdiscountProperty);
                    }


                    decimal valForTotal = 890;
                    if (entity.Properties.Contains("totalamount"))
                    {
                        ((CrmMoney)entity.Properties["totalamount"]).Value = valForTotal;
                    }
                    else
                    {
                        CrmMoneyProperty totalamountProperty = new CrmMoneyProperty("totalamount", new CrmMoney(valForTotal));
                        entity.Properties.Add(totalamountProperty);
                    }

                    service.Update(entity);
                }

            }
         }


er überschreibt zwar discountamount, aber bei totalamount laufen wir immer in den else zweig rein und crm überschreibt das hardcodierte 890 wieder mit einem berechneten wert...

Was müsste ich ändern, damit es dennoch klappt?

Viele Grüße
Pascal

Re: Optionale Produkte im Angebot

5. Februar 2010 16:47

Hallo Pascal,

da fehlt ja auch die Hälfte. Schaut euch einmal im SDK die Beispiele an und nehmt diese als Vorlage.
Wo z.B. ist in deinem Code das Target?

Re: Optionale Produkte im Angebot

11. Februar 2010 10:20

Guten Morgen,

ich habe jetzt folgenden Code von unserem Entwickler zurückbekommen:

Code:
                   //1) Get the entity
                    TargetRetrieveQuote target = new TargetRetrieveQuote();
                    target.EntityId = ((Key)((DynamicEntity)context.InputParameters[ParameterName.Target]).Properties["quoteid"]).Value;
                    RetrieveRequest request = new RetrieveRequest();
                    request.Target = target;
                    request.ColumnSet = new AllColumns();
                    RetrieveResponse response = (RetrieveResponse)service.Execute(request);

                    //2) Update some fields
                    quote quoteEntity = (quote)response.BusinessEntity;
                    ///quoteEntity.discountamount = new CrmMoney(1234); // for this is working
                    quoteEntity.totalamount = new CrmMoney(4567);

                    //3) Execute request
                    TargetUpdateQuote targetQuote = new TargetUpdateQuote();
                    targetQuote.Quote = quoteEntity;
                    UpdateRequest uRequest = new UpdateRequest();
                    uRequest.Target = targetQuote;
                    UpdateResponse uResponse = (UpdateResponse)service.Execute(uRequest);


Ich bin für jeden Hinweis dankbar!

Viele Grüße
Pascal

Re: Optionale Produkte im Angebot

11. Februar 2010 12:36

Hallo Pascal,

sag eurem Entwickler einmal, er soll sich mit der Technik der Pre und Post Images im CRM beschäftigen. Das ist im SDK nachzulesen.

Re: Optionale Produkte im Angebot

19. Februar 2010 15:18

Hallo Michael,

da ich eine ähnliche Problematik habe, versuche ich zu verstehen was du mit
Euer Entwickler muss nur auf das Update des Angebotes reagieren, die Werte neu berechnen und dem Post-Image zuweisen.

gemeint hast.

Ein Post-Image steht mir ja logischerweise nur zur Verfügung, wenn ich das Plug-In das Post Stage Plug-In registriere (oder irre ich mich da?). Wenn ich in diesem Fall die Attribute im Post-Image ändere, ändert das an der Entität an sich ja nichts. Das Post-Image repräsentiert nach meinem Verständnis die Attribute der Entität nach dem Speichern der Änderungen die durch den Standard-Code vorgenommen wurden. Also muss ich die Entität per Update-Methode (mit dem Post-Image) aktualisieren. Wenn ich das aber so mache wird ja wieder ein Update-Event erzeugt, der Standard-Code durchlaufen und ich würde in einer Endlosschleife landen. Wie schaffe ich es also die Daten der Entität zu ändern ohne Ihre Update Methode aufzurufen, bzw. ohne das die Berechnung nochmal ausgeführt wird?

Korrigiere mich bitte, wenn in meiner Denkweise was falsch ist, aber mir ist nicht klar wie sich dieses Problem lösen lässt.

Vielen Dank und viele Grüße,
Florian

Re: Optionale Produkte im Angebot

19. Februar 2010 15:48

Hallo Florian,

Ein Post-Image steht mir ja logischerweise nur zur Verfügung, wenn ich das Plug-In das Post Stage Plug-In registriere

genau.

Wenn ich in diesem Fall die Attribute im Post-Image ändere, ändert das an der Entität an sich ja nichts. Das Post-Image repräsentiert nach meinem Verständnis die Attribute der Entität nach dem Speichern der Änderungen die durch den Standard-Code vorgenommen wurden

Das ist nicht ganz richtig. Das Post Image representiert die Attribute die gespeichert würden, wenn du das nicht abfängst. Darum kannst du auch nicht in eine Endlosschleife laufen, es sei denn, es gibt ein zweites Plugin auf dieser Entität.

Re: Optionale Produkte im Angebot

19. Februar 2010 16:31

Hallo Michael,
danke für die Berichtigung. Wie gesagt ich versuche die Thematik gerade zu erarbeiten und finde nur relative magere Informationen.

Wenn ich dich richtig verstehe müsste ich einfach das PostEntityImage laden und danach die Attribute verändern... also quasi so:
Code:
            if (context.PostEntityImages.Contains("Quote") && context.PostEntityImages["Quote"] is DynamicEntity)
            {
                DynamicEntity entity = (DynamicEntity)context.PostEntityImages["Quote"];
                if(entity.Properties.Contains("name")){   
                     entity.Properties.Remove("name");
                }
                entity.Properties.Add(new StringProperty("name", "Hugo"));
            }


In diesem Fall sollte die Bezeichnung des Angebots vom alten Namen auf "Hugo" wechseln, was sie nicht tut. Ich vermute hier fehlt noch ein Schritt oder ich habe das ganze Konzept nicht verstanden.

Ich hoffe du kannst weiterhelfen.
Vielen Dank und viele Grüße,
Florian

Re: Optionale Produkte im Angebot

19. Februar 2010 17:38

Hallo Florian,

du hast zwar den Wert schon geändert, aber wo schreibst du ihn zurüch in das Image?

Re: Optionale Produkte im Angebot

19. Februar 2010 18:50

Hallo Michael,

genau dieser Schritt fehlt mir, kannst du mir da weiterhelfen? Ich finde auch irgendwie keine geeignete Dokumentation im SDK (vielleicht hast du ja einen Tip wo ich suchen muss, ich finde entweder Informationen zu PreImage Veränderungen oder zu Veränderungen von anderen Entitäten. Aber leider nicht zur Veränderung des eigenen PostImages). Ich verändere ja das Post-Image, aber wie genau aktualisere ich die Daten bzw. schreibe das Image zurück. Mit service.update(entity) erreiche ich ja nicht was ich will, weil da wird ja wieder die Standard Update Prozedur durchlaufen.

Viele Grüße und vielen Dank,
Florian

Re: Optionale Produkte im Angebot

20. Februar 2010 11:33

Hallo Florian,

schau dir einmal diese Artikel an:
http://www.eggheadcafe.com/software/asp ... e-and.aspx
http://nishantrana.wordpress.com/2008/0 ... in-crm-40/
http://stateracrm.blogspot.com/2008/07/ ... art-7.html
http://blogs.msdn.com/crm/archive/2008/ ... m-4-0.aspx

Re: Optionale Produkte im Angebot

22. Februar 2010 12:45

Hallo Michael,

danke für die Links, die meisten davon hatte ich schon durchgelesen, leider keine Antwort auf mein Problem gefunden (oder die Antworten falsch verstanden). Nochmal eine grundsätzliche Frage:
- Post Image: this will contain the first-, lastname and emailaddress1
field. These are all the fields you specify in the image and have a value in
the database AFTER the update is commited to the database.

Klingt für mich als wäre das Image schon zurück auf die Datenbank geschrieben worden, was aber dem widerspricht was du weiter vorne geschrieben hast, was mich gerade etwas verwirrt. Was stimmt jetzt? Oder widerspricht sich das ganze nicht und das AFTER the update is commited bezieht sich darauf, wenn du da nicht davor eingreifst?

Letztlich muss ich ja dafür sorgen, dass die geänderten Daten aus dem Image in die Datenbank zurückgeschrieben werden. Das einzige was ich dazu gefunden habe wäre dabei folgendes:
Code:
        public void Execute(IPluginExecutionContext context)
        {
            // Verify we have an entity to work with
            if (context.PostEntityImages.Contains("Quote") && context.PostEntityImages["Quote"] is DynamicEntity)
            {
                ICrmService service = context.CreateCrmService(true);
                // Obtain the target business entity from the input parmameters.
                DynamicEntity entity = (DynamicEntity)context.PostEntityImages["Quote"];
                if (entity.Properties.Contains("name"))
                {
                    entity.Properties.Remove("name");
                }
                entity.Properties.Add(new StringProperty("name", "Hugo"));
                service.Update(entity);
            }
         }


Hierbei würde ich also den WebService auffordern die Daten nochmal zu aktualisieren (was auch klappt), allerdings durchläuft er a) nochmal alle Standardprozesse des Updates und b) muss ich verhindern dass er in eine Endlosschleife läuft, da das Plug-In selber ja auch wieder aufgerufen wird, nachdem der Standard-Update-Prozess durchlaufen wurde. Das kann ich natürlich über die Depth Variable oder die Correlation ID machen. Das würde auch die Probleme beim Namensattribut lösen. Wie es es aber mit dem TotalValue Attribut von Pascal. Dieses wird im Standard-Update-Prozess ja wieder aktualisiert und dadurch steht wieder der berechnete Wert in der Datenbank, da das Post-Plug-In ja nicht durchlaufen wird (um die Endlosschleife zu verhinden).

Im Prinzip ergeben sich daraus 2 Fragen:
1) Liege ich mit meinen Aussagen komplett daneben und habe was grundsätzliches übersehen?
2) Ist es überhaupt möglich berechnete Felder wie bspw. die Total Amount manuell zu überschreiben? Wenn ja, wie bekomme ich dann die Daten aus dem geänderten Post-Image in die Datenbank (ohne die service.Update-Methode)?

Ich habe wirklich versucht selber in Foren eine Lösung zu finden, aber leider nichts passendes gefunden. Wie gesagt, Felder die vom Standard-Prozess nicht verändert werden können auch so geändert werden, Probleme habe ich mit berechneten Feldern.

Ich hoffe du kannst etwas Licht ins Dunkle bringen.

@Pallanio: Wenn ich das richtig sehe willlst du die TotalAmount überschreiben, um keinen Discount ausweisen zu müssen (Was ja irgendwie auch sinnfrei wäre), oder verstehe ich da falsch?

Vielen Dank und viele Grüße,
Florian

Re: Optionale Produkte im Angebot

22. Februar 2010 17:50

Hallo Florian,

das Post Image enthält die Daten nach dem Schreiben in die DB. Ein ändern des Images und erneutes speichern mit .Update erzeugt wieder eine Update-Message auf der Entuität und dein Plugin startet erneut. Um jetzt eine Endlosschleife zu verhindern, gibt es verschiedene Möglichkeiten. Ist es dein einzigstes PlugIn, ist dies relativ einfach, du musst nur prüfen, ob das Update durch ein PlugIn ausgelöst wurde.

Re: Optionale Produkte im Angebot

23. Februar 2010 10:27

Hallo Michael,

gibt es außer .update noch eine andere Methode die Daten aus dem geänderten Image zu schreiben? Wenn nein sehe ich keine Möglichkeit Pascals Problem mit der TotalAmount zu lösen, weil diese beim Aufrufen der .update-Methode ja automatisch von den Standardprozessen überschrieben wird.

Falls es da doch eine Lösung gibt wäre ich sehr gespannt wie das aussieht. Weil PreImage-Änderungen bringen ja auch nicht viel.

Vielen Dank und viele Grüße,
Florian

Re: Optionale Produkte im Angebot

2. März 2010 17:12

Ich habe mich jetzt mal noch weiter schlau gemacht. Ein Blick ins SDK hätte mir schon vorher gesagt, dass TotalAmount ein Read-Only Feld ist und somit keine Änderungen möglich sind. Auch die Änderung der internen Berechnungsroutinen ist nicht möglich. Also bleibt für pallinio (was ich inzwischen auch für die sauberste Lösung halte) entweder ein eigenes Feld zu erstellen, dass den entsprechend berechneten Wert enthält und der dann auch bspw. in den Reports genutzt wird oder alternativ der Weg über den manuellen Rabatt (was ich für betriebswirtschaftlich unschön halte).

Viele Grüße,
Florian

Re: Optionale Produkte im Angebot

4. März 2010 16:23

Hallo Florian,

Ein Blick ins SDK hätte mir schon vorher gesagt, dass TotalAmount ein Read-Only Feld ist und somit keine Änderungen möglich sind

auf die Idee hätte ich auch kommen können, danke für deine Rückmeldung.