Prescription sale example

Overview

This example shows a more involved example of a sale. In this example, a pharmacist serves a customer who hands in a prescription and additionally wants to buy a self-service article.

See Examples for an explanation of the elements shown here.

Example

Starting the sale

While no sale (or pickup) is in progress, the visavia repeatedly checks if the posps server is available by calling readyForSale.


readyForSale

Request

<sale:readyForSale>
    <posId code="visavia-1"/>
</sale:readyForSale>

Response

<sale:readyForSaleResponse>
    <readyForSale>true</readyForSale>
</sale:readyForSaleResponse>

If the server returns true, the visavia shows a welcome screen to prospective customers. Should the server return false or be not reachable, the visavia goes out of order until a later call succeeds.

welcome screen

When a customer clicks on the touchscreen, he is asked how he wants to proceed.

customer choice

The customer has a prescription which he wants to hand in. He therefore clicks Fill a prescription. The visavia reacts by starting a new sale and calling a pharmacist who is free to serve the customer. The server generates an id for the new sale and returns it.


startSale

Request

<sale:startSale>
    <posId code="visavia-1"/>
</sale:startSale>

Response

<sale:startSaleResponse>
    <sale>
        <saleId code="example-2" />
        
        <total>
            <total>0</total>
        </total>
        
    </sale>
</sale:startSaleResponse>

A short while later, a pharmacist is ready to serve the customer and takes control of the visavia. In the terms of the posps interface, the pharmacist is the operator. The visavia notifies the server by calling setSaleOperator.


setSaleOperator

Request

        <sale:setSaleOperator>
            <saleId code="example-2" />
            
            <operator>
                <!-- The name shown on the customer display and receipts. -->
                <displayName>Mr. Doe</displayName>
                <!-- Full name of the operator, mainly used for documenting the sale. -->
                <fullName>John Doe</fullName>
                
                <!-- The visavia uses GUIDs to identify operators. This is only
                    by convention and not mandated by the posps interface. Other
                    clients might use login names or provide no operatorIds at all. -->
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                
                <organization>Example visavia Services Ltd.</organization>
                
                <!-- Like with the operatorId, the use of a GUID is not mandatory. -->
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

        </sale:setSaleOperator>

Response

    <sale:setSaleOperatorResponse>
        <sale>
            <saleId code="example-2" />
            
            <!-- The server has added the operator element sent by the client. -->
            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <total>
                <total>0</total>
            </total>
            
        </sale>
    </sale:setSaleOperatorResponse>

The pharmacist asks the customer to insert his prescription into the scanner. The prescription is scanned and the image is shown to the pharmacist.

Adding the customer information

Since the customer tells the pharmacist that he has a customer account at the pharmacy and that the prescription is for him, the pharmacists sets the customer of the sale. To do this, he first has to search for the customer entry in the database. He searches for the name printed on the prescription.


searchPerson

Request

        <search:searchPerson>
        
            <searchpattern>
            
                <condition>
                    <firstName>Robert</firstName>
                </condition>
                
                <condition>
                    <lastName>Smith</lastName>
                </condition>
                
                <condition>
                    <!-- Person may be either customer or patient (or both). -->
                    <role>customer</role>
                    <role>patient</role>
                </condition>

                <order>
                    <lastName />
                </order>
                
            </searchpattern>
            
            <resultTemplate>
                <personData>
                    <personGUID code="template" />
                    <customernumber />
                    <firstName />
                    <lastName />
                    <born>0001-01-01</born>
                </personData>
            </resultTemplate>
            
            <maxElements>50</maxElements>
            <posId code="visavia-1" />
        </search:searchPerson>

Response

        <search:searchPersonResponse>
            <searchResultId code="example-searchresult-2" />
            <searchResult>
                <previous>0</previous>
                <remaining>0</remaining>
                
                <!-- Only one "Robert Smith" was found. -->
                <element xsi:type="pptype:PersonSearchResultElement">
                    <personData>
                        <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                        <customernumber>123456789</customernumber>
                        <firstName>Robert</firstName>
                        <lastName>Smith</lastName>
                        <born>1970-06-07</born>
                    </personData>

                </element>

            </searchResult>
        </search:searchPersonResponse>

Since the name and date of birth of the search result match the data on the prescription, the pharmacist knows that he has found the correct person. He sets the person as customer. The visavia calls addSalePerson with the personGUID obtained from the search result. The server adds the person and generates a personId local to the sale.


addSalePerson

Request

<sale:addSalePerson>
    <saleId code="example-2"/>

    <addPersonData>
        <!-- The personGUID is taken from the search result. -->
        <personGUID code="74f7da0796efa7023607a7eaec300f42" />
    </addPersonData>
    
</sale:addSalePerson>

Response

    <sale:addSalePersonResponse>
        <sale>
            <saleId code="example-2" />

            <!-- The server has added the person which is set as customer. -->
            <person>
                <!-- this is the personId generated by the server for this sale only. -->
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    
                    <!-- ... other optional data left out for brevity -->
                    
                    <!-- Patient information. This becomes relevant when the
                         customer is set as prescription patient. -->
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <!-- Just an example note. The note should contain anything
                        which the pharmacist should know when he serves this customer. -->
                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <total>
                <total>0</total>
            </total>
            
        </sale>
    </sale:addSalePersonResponse>

The visavia then calls setSaleCustomer with the personId of the added person.


setSaleCustomer

Request

<sale:setSaleCustomer>
    <saleId code="example-2"/>

    <!-- The personId is taken from the search result. -->
    <customerId code="person-1234" />
    
</sale:setSaleCustomer>

Response

    <sale:setSaleCustomerResponse>
        <sale>
            <saleId code="example-2" />

            <!-- The server has added the person which is set as customer. -->
            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    
                    <!-- ... other optional data left out for brevity -->
                    
                    <!-- Patient information. This becomes relevant when the
                         customer is set as prescription patient. -->
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <!-- Just an example note. The note should contain anything
                        which the pharmacist should know when he serves this customer. -->
                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <!-- The newly added customer element references the person element
                set above. -->
            <customerId code="person-1234"/>

            <total>
                <total>0</total>
            </total>
            
        </sale>
    </sale:setSaleCustomerResponse>

Adding the prescribed article

The pharmacist now wants to add the prescribed article to the sale. He searches for it by its name.


searchArticle

Request

      <search:searchArticle>
      
         <searchpattern>

            <condition>
                <!-- The pharmacist is too lazy to type capitals. -->
                <name>captopril</name>
            </condition>

            <condition>
               <!-- The pharmacist wants to limit the results to only articles
                    which he can sell. He can toggle this behaviour in his GUI. -->
               <inStock />
            </condition>

            <!-- Order results by article name. -->
            <order>
                <name />
            </order>
         </searchpattern>
         
         <searchContext>
            <saleId code="example-2" />
         </searchContext>
         
         <resultTemplate>
            <!-- List all elements the client is interested in. The values
                 are unimportant. The presence alone indicates that the server
                 should fill these elements with the actual values. This can
                 be compared to listing the columns in an SQL SELECT statement. 
              -->
                 
            <!-- In further calls, the visavia will use the articleId
                 instead of the PZN to refer to this articles. -->
            <articleId code="template"/>
            
            <name />
            <manufacturer />
            <price>0</price>
            <stock>0</stock>
            <packaging>
               <description />
            </packaging>
            
            <pharmaceutic>
                <countrySpecific xsi:type="pptype:PharmaceuticArticleDE">
                    <pzn>1234567</pzn>
                    <festbetrag>0</festbetrag>
                    <arzneimittel>false</arzneimittel>
                    <apothekenpflicht>false</apothekenpflicht>
                    <rezeptpflicht>false</rezeptpflicht>
                    <betaeubungsmittel>false</betaeubungsmittel>
                    <drogeChemikalie>false</drogeChemikalie>
                    <importReimport>false</importReimport>
                    <lifestyle>no</lifestyle>
                    <negativliste>no</negativliste>
                    <normpackungsgroesse>N1</normpackungsgroesse>
                    <tierarzneimittel>false</tierarzneimittel>
                    <transfusionsgesetz>false</transfusionsgesetz>
                    <zuzfrei31SgbTsr>false</zuzfrei31SgbTsr>
                    <zuzfrei31SgbFeb>false</zuzfrei31SgbFeb>
                    <hatRabattvertraege>false</hatRabattvertraege>
                </countrySpecific>
            </pharmaceutic>
         </resultTemplate>
         
         <!-- 500 elements at once should not be a problem in local networks -->
         <maxElements>500</maxElements>

         <posId code="visavia-1"/>
      </search:searchArticle>

Response

        <search:searchArticleResponse>
            <searchResultId code="example-searchresult-1" />
            
            <searchResult>
                <!-- This is the first result for this search. -->
                <previous>0</previous>
                <!-- There are no more search results remaining after the ones
                    contained in this response. -->
                <remaining>0</remaining>

                <element xsi:type="pptype:ArticleSearchResultElement">
                    <!-- In this and further examples, the posps server uses 
                         PZNs for articleIds, which is customary for German
                         pharmacy IT systems but not required by the 
                         specification. -->
                    <articleId code="0066393" />

                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <price>1046</price><!-- EUR10.46 -->
                    <stock>8</stock>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticArticleDE">
                            <pzn>4479146</pzn>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <arzneimittel>true</arzneimittel>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                            <betaeubungsmittel>false</betaeubungsmittel>
                            <drogeChemikalie>false</drogeChemikalie>
                            <importReimport>false</importReimport>
                            <lifestyle>no</lifestyle>
                            <negativliste>no</negativliste>
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <tierarzneimittel>false</tierarzneimittel>
                            <transfusionsgesetz>false</transfusionsgesetz>
                            <zuzfrei31SgbTsr>false</zuzfrei31SgbTsr>
                            <zuzfrei31SgbFeb>true</zuzfrei31SgbFeb>
                            <hatRabattvertraege>true</hatRabattvertraege>
                        </countrySpecific>
                    </pharmaceutic>
                </element>

                <!-- ... the remaining search result elements are left out for brevity -->

            </searchResult>        
        </search:searchArticleResponse>

The pharmacist chooses the article from the search result and adds it to the sale as a position sold on prescription. The visavia first adds the prescription to the sale.


addSalePrescription

Request

        <sale:addSalePrescription>
            <saleId code="example-2" />

            <prescriptionData>
                
                <!-- The customer is also the prescription patient. -->
                <patientId code="person-1234" />
                
                <countrySpecific xsi:type="pptype:PrescriptionDE">
                    <rezeptart>gkv</rezeptart>
                    <gebuehrenfrei>false</gebuehrenfrei>
                    <kinderrezept>false</kinderrezept>
                    <noctu>false</noctu>
                </countrySpecific>

                <!-- The pharmacist hasn't entered the other prescription data. 
                    This data will have to be entered into the server later.
                    (Mechanisms for this are not covered by the posps specification.) -->
            </prescriptionData>

        </sale:addSalePrescription>

Response

    <sale:addSalePrescriptionResponse>
        <sale>
            <saleId code="example-2" />

            <!-- This person is now both the customer and the prescription patient. -->
            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>
                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>

            <!-- The server adds the prescription to the sale and creates a
                prescriptionId. -->
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />

                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <customerId code="person-1234"/>

            <total>
                <total>0</total>
            </total>
            
        </sale>
    </sale:addSalePrescriptionResponse>

Now the visavia adds the new position for the article which references the prescription. This means that the position is sold on prescription and the server should take this into account when calculating the prices.


addSalePosition

Request

        <sale:addSalePosition>
            <saleId code="example-2" />

            <addPositionData>
                <!-- The articleId is taken from the search result. -->
                <articleId code="0066393" />

                <!-- This article is sold on prescription. The prescriptionId is
                    taken from the previous sale result. -->
                <prescriptionId code="prescription-1" />

                <!-- The customer needs one pack. -->
                <amount>1</amount>

            </addPositionData>
        </sale:addSalePosition>

Response

    <sale:addSalePositionResponse>
        <sale>
            <saleId code="example-2" />

            <!-- The following position was created by the server in response
                to the addSalePosition request. -->
            <position>
                <positionId code="position-1" />
                
                <positionData>
                    <articleId code="0066393" />
                    
                    <!-- This position is sold on prescription. -->
                    <prescriptionId code="prescription-1" />
                    
                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <amount>1</amount>
                    <delivered>0</delivered>
                    
                    <!-- This position is paid for by the health insurance. The
                         price the customer has to pay is therefore EUR0.00. -->
                    <articlePrice>0</articlePrice>
                    <positionPrice>0</positionPrice>
                    
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>0066393</pzn>
                            <retailPrice>1046</retailPrice><!-- EUR10.46 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>

            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>
            
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />
                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <!-- The total is still EUR0.00 since the article is paid for
                by the health insurance. -->
            <total>
                <total>0</total>
            </total>
            
        </sale>
    </sale:addSalePositionResponse>

Other than with a selfservice sale, the visavia orders articles directly after the pharmacist has selected them. It calls Order.orderArticles. This call is done in parallel to the sale process. The pharmacist can continue to serve the customer while the article is on its way from the pharmacy robot to the visavia.


orderArticles

Request

<order:orderArticles>
    <order>
        <article>
            <articleId code="0066393" />
            <positionId code="position-1" />
            <amount>1</amount>
        </article>
    </order>
    
    <posId code="visavia-1" />
    
    <saleId code="example-2" />
    
</order:orderArticles>

Response

<order:orderArticlesResponse>
    <orderId code="order-id-2" />
    
    <saleId code="example-2" />
    
    <articles>
        <article>
            <articleId code="0066393" />
            <positionId code="position-1" />
            <ordered>1</ordered>
            <delivered>1</delivered>
        </article>
    </articles>
    
</order:orderArticlesResponse>

The pack has already arrived when the method returned, so there is no need to call trackOrder.

Adding an OTC article

In addition to filling his prescription, the customer also needs something against his headache. He asks the pharmacist for a pack of Aspirin. The pharmacist does another article search.


searchArticle

Request

      <search:searchArticle>
      
         <searchpattern>

            <condition>
                <name>aspirin</name>
            </condition>

            <condition>
               <!-- The pharmacist wants to limit the results to only articles
                    which he can sell. He can toggle this behaviour in his GUI. -->
               <inStock />
            </condition>

            <!-- Order results by article name. -->
            <order>
                <name />
            </order>
         </searchpattern>
         
         <searchContext>
            <saleId code="example-2" />
         </searchContext>
         
         <resultTemplate>
            <!-- List all elements the client is interested in. The values
                 are unimportant. The presence alone indicates that the server
                 should fill these elements with the actual values. This can
                 be compared to listing the columns in an SQL SELECT statement. 
              -->
                 
            <!-- In further calls, the visavia will use the articleId
                 instead of the PZN to refer to this articles. -->
            <articleId code="template"/>
            
            <name />
            <manufacturer />
            <price>0</price>
            <stock>0</stock>
            <packaging>
               <description />
            </packaging>
            
            <pharmaceutic>
                <countrySpecific xsi:type="pptype:PharmaceuticArticleDE">
                    <pzn>1234567</pzn>
                    <festbetrag>0</festbetrag>
                    <arzneimittel>false</arzneimittel>
                    <apothekenpflicht>false</apothekenpflicht>
                    <rezeptpflicht>false</rezeptpflicht>
                    <betaeubungsmittel>false</betaeubungsmittel>
                    <drogeChemikalie>false</drogeChemikalie>
                    <importReimport>false</importReimport>
                    <lifestyle>no</lifestyle>
                    <negativliste>no</negativliste>
                    <normpackungsgroesse>N1</normpackungsgroesse>
                    <tierarzneimittel>false</tierarzneimittel>
                    <transfusionsgesetz>false</transfusionsgesetz>
                    <zuzfrei31SgbTsr>false</zuzfrei31SgbTsr>
                    <zuzfrei31SgbFeb>false</zuzfrei31SgbFeb>
                    <hatRabattvertraege>false</hatRabattvertraege>
                </countrySpecific>
            </pharmaceutic>
         </resultTemplate>
         
         <!-- 500 elements at once should not be a problem in local networks -->
         <maxElements>500</maxElements>

         <posId code="visavia-1"/>
      </search:searchArticle>

Response

        <search:searchArticleResponse>
            <searchResultId code="example-searchresult-1" />
            
            <searchResult>
                <!-- This is the first result for this search. -->
                <previous>0</previous>
                <!-- There are no more search results remaining after the ones
                    contained in this response. -->
                <remaining>0</remaining>

                <element xsi:type="pptype:ArticleSearchResultElement">
                    <!-- In this and further examples, the posps server uses 
                         PZNs for articleIds, which is customary for German
                         pharmacy IT systems but not required by the 
                         specification. -->
                    <articleId code="4355264" />

                    <name>ASPIRIN DIREKT Kautabl.</name>
                    <manufacturer>Bayer</manufacturer>
                    <price>797</price><!-- EUR7.97 -->
                    <stock>5</stock>
                    <packaging>
                        <size>20</size>
                        <unit>Pc</unit>
                    </packaging>
                    
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticArticleDE">
                            <pzn>4355264</pzn>
                            <festbetrag>262</festbetrag><!-- EUR2.62 -->
                            <arzneimittel>true</arzneimittel>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>false</rezeptpflicht>
                            <betaeubungsmittel>false</betaeubungsmittel>
                            <drogeChemikalie>false</drogeChemikalie>
                            <importReimport>false</importReimport>
                            <lifestyle>no</lifestyle>
                            <negativliste>no</negativliste>
                            <normpackungsgroesse>N1</normpackungsgroesse>
                            <tierarzneimittel>false</tierarzneimittel>
                            <transfusionsgesetz>false</transfusionsgesetz>
                            <zuzfrei31SgbTsr>false</zuzfrei31SgbTsr>
                            <zuzfrei31SgbFeb>false</zuzfrei31SgbFeb>
                            <hatRabattvertraege>false</hatRabattvertraege>
                        </countrySpecific>
                    </pharmaceutic>
                </element>

                <!-- ... the remaining search result elements are left out for brevity -->

            </searchResult>        
        </search:searchArticleResponse>

The pharmacist recommends articles from the search results, and the customer says which he wants. The pharmacist selects the appropriate search result entry and adds it as a sale position. This position is not sold on prescription, the customer will have to pay for it.


addSalePosition

Request

        <sale:addSalePosition>
            <saleId code="example-2" />

            <addPositionData>
                <!-- The articleId is taken from the search result. -->
                <articleId code="4355264" />

                <!-- This article is not sold on prescription. There is
                     therefore no prescriptionId. -->

                <!-- The pharmacist chooses to add one pack. -->
                <amount>1</amount>

            </addPositionData>
        </sale:addSalePosition>

Response

    <sale:addSalePositionResponse>
        <sale>
            <saleId code="example-2" />

            <!-- This is the position added earlier. -->
            <position>
                <positionId code="position-1" />
                
                <positionData>
                    <articleId code="0066393" />
                    
                    <!-- This position is sold on prescription. -->
                    <prescriptionId code="prescription-1" />
                    
                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <amount>1</amount>
                    <delivered>0</delivered>
                    <articlePrice>0</articlePrice>
                    <positionPrice>0</positionPrice>
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>0066393</pzn>
                            <retailPrice>1046</retailPrice><!-- EUR10.46 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>
            
            <!-- The following position was created by the server in response
                to the addSalePosition request. -->
            <position>
                <positionId code="position-2" />
                
                <positionData>
                    <articleId code="4355264" />
                    
                    <name>ASPIRIN DIREKT Kautabl.</name>
                    <packaging>
                        <size>20</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>Bayer</manufacturer>
                    <amount>1</amount>
                    <delivered>0</delivered>
                    
                    <!-- The customer has to pay for this article himself. -->
                    <articlePrice>797</articlePrice>
                    <positionPrice>797</positionPrice>
                    
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>4355264</pzn>
                            <retailPrice>797</retailPrice><!-- EUR7.97 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>262</festbetrag><!-- EUR2.62 -->
                            <normpackungsgroesse>N1</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>false</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>

            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>
            
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />
                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <!-- The total is updated for the newly added position. -->
            <total>
                <vat>
                    <vatRate>19</vatRate><!-- 19% VAT -->
                    <price>128</price><!-- EUR1.28 -->
                </vat>
                <total>797</total><!-- EUR7.97 -->
            </total>

        </sale>
    </sale:addSalePositionResponse>

The article is ordered from the robot like the previous article. The orderArticle call is left out for brevitys sake.

The customer would like to buy two packs of Aspirin. The pharmacist increases the amount, which triggers an editSalePosition call.


editSalePosition

Request

        <sale:editSalePosition>
            <saleId code="example-2" />
            <positionId code="position-2" />

            <editPositionData>

                <!-- The amount is increased by 1, the new total amount is 2. -->
                <amount>2</amount>

            </editPositionData>
        </sale:editSalePosition>

Response

    <sale:editSalePositionResponse>
        <sale>
            <saleId code="example-2" />

            <position>
                <positionId code="position-1" />
                
                <positionData>
                    <articleId code="0066393" />
                    <prescriptionId code="prescription-1" />
                    
                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <amount>1</amount>
                    <delivered>0</delivered>
                    <articlePrice>0</articlePrice>
                    <positionPrice>0</positionPrice>
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>0066393</pzn>
                            <retailPrice>1046</retailPrice><!-- EUR10.46 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>
            
            <position>
                <positionId code="position-2" />
                
                <positionData>
                    <articleId code="4355264" />
                    
                    <name>ASPIRIN DIREKT Kautabl.</name>
                    <packaging>
                        <size>20</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>Bayer</manufacturer>
                    
                    <!-- The server has updated the amount. -->
                    <amount>2</amount>

                    <delivered>0</delivered>

                    <!-- The position price is calculated as 2 x article price.
                         This doesn't have to be the case if the server applies
                         quantity rebates. -->
                    <articlePrice>797</articlePrice>
                    <positionPrice>1594</positionPrice><!-- EUR15.94 -->

                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>4355264</pzn>
                            <retailPrice>797</retailPrice><!-- EUR7.97 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>262</festbetrag><!-- EUR2.62 -->
                            <normpackungsgroesse>N1</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>false</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>

            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>
            
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />
                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <!-- The total is updated again. -->
            <total>
                <vat>
                    <vatRate>19</vatRate><!-- 19% VAT -->
                    <price>255</price><!-- EUR2.55 -->
                </vat>
                <total>1594</total><!-- EUR15.94 -->
            </total>

        </sale>
    </sale:editSalePositionResponse>

The pack is ordered via orderArticle as before.

Payment and checkout

The customer now has everything which he wants. He tells the pharmacist that he wants to pay by card. The payment procedure is started and the customer pays the EUR15.94 which was calculated by the server.

The articles have already been delivered to the output tray. The visavia unlocks it to dispense them. It confirms this action to the server.


confirmSaleDelivery

Request

<sale:confirmSaleDelivery>
    <saleId code="example-2" />
    
    <deliveredPosition>
        <positionId code="position-1" />
        
        <!-- One pack has been delivered for this position. -->
        <delivered>1</delivered>
        
    </deliveredPosition>
    
    <deliveredPosition>
        <positionId code="position-2" />
        
        <!-- Two packs have been delivered for this position. -->
        <delivered>2</delivered>
        
    </deliveredPosition>
</sale:confirmSaleDelivery>

Response

    <sale:confirmSaleDeliveryResponse>
        <sale>
            <saleId code="example-2" />

            <position>
                <positionId code="position-1" />
                
                <positionData>
                    <articleId code="0066393" />                    
                    <prescriptionId code="prescription-1" />
                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <amount>1</amount>
                    
                    <!-- The server has updated the delivered amount. -->
                    <delivered>1</delivered>
                    
                    <articlePrice>0</articlePrice>
                    <positionPrice>0</positionPrice>
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>0066393</pzn>
                            <retailPrice>1046</retailPrice><!-- EUR10.46 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>
            
            <position>
                <positionId code="position-2" />
                
                <positionData>
                    <articleId code="4355264" />
                    
                    <name>ASPIRIN DIREKT Kautabl.</name>
                    <packaging>
                        <size>20</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>Bayer</manufacturer>
                    <amount>2</amount>
                    
                    <!-- The server has updated the delivered amount. -->
                    <delivered>2</delivered>

                    <articlePrice>797</articlePrice>
                    <positionPrice>1594</positionPrice><!-- EUR15.94 -->

                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>4355264</pzn>
                            <retailPrice>797</retailPrice><!-- EUR7.97 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>262</festbetrag><!-- EUR2.62 -->
                            <normpackungsgroesse>N1</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>false</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>

            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>
            
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />
                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <total>
                <vat>
                    <vatRate>19</vatRate><!-- 19% VAT -->
                    <price>255</price><!-- EUR2.55 -->
                </vat>
                <total>1594</total><!-- EUR15.94 -->
            </total>

        </sale>
    </sale:confirmSaleDeliveryResponse>

At this point it is clear that the payment is final and can't be canceled any longer. The visavia therefore invokes the confirmSalePayment operation.


confirmSalePayment

Request

<sale:confirmSalePayment>
    <saleId code="example-2" />
    
    <payment xsi:type="pptype:PaymentCard">
        <type>Maestro</type>
    </payment>
    <canceled>false</canceled>
    
</sale:confirmSalePayment>

Response

    <sale:confirmSalePaymentResponse>
        <sale>
            <saleId code="example-2" />

            <position>
                <positionId code="position-1" />
                
                <positionData>
                    <articleId code="0066393" />                    
                    <prescriptionId code="prescription-1" />
                    <name>CAPTOPRIL 12,5 1A Pharma Tabl.</name>
                    <packaging>
                        <size>100</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>1A Pharma GmbH</manufacturer>
                    <amount>1</amount>
                    <delivered>1</delivered>
                    <articlePrice>0</articlePrice>
                    <positionPrice>0</positionPrice>
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>0066393</pzn>
                            <retailPrice>1046</retailPrice><!-- EUR10.46 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>1315</festbetrag><!-- EUR13.15 -->
                            <normpackungsgroesse>N3</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>true</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>
            
            <position>
                <positionId code="position-2" />
                
                <positionData>
                    <articleId code="4355264" />
                    
                    <name>ASPIRIN DIREKT Kautabl.</name>
                    <packaging>
                        <size>20</size>
                        <unit>Pc</unit>
                    </packaging>
                    <manufacturer>Bayer</manufacturer>
                    <amount>2</amount>
                    <delivered>2</delivered>
                    <articlePrice>797</articlePrice>
                    <positionPrice>1594</positionPrice><!-- EUR15.94 -->
                    <vatRate>19</vatRate>
                    <pharmaceutic>
                        <countrySpecific xsi:type="pptype:PharmaceuticPositionDE">
                            <pzn>4355264</pzn>
                            <retailPrice>797</retailPrice><!-- EUR7.97 -->
                            <zuzahlung>0</zuzahlung>
                            <mehrkostenanteil>0</mehrkostenanteil>
                            <festbetrag>262</festbetrag><!-- EUR2.62 -->
                            <normpackungsgroesse>N1</normpackungsgroesse>
                            <apothekenpflicht>true</apothekenpflicht>
                            <rezeptpflicht>false</rezeptpflicht>
                        </countrySpecific>
                    </pharmaceutic>
                </positionData>
            </position>

            <person>
                <personId code="person-1234" />
                
                <personData>
                    <personGUID code="74f7da0796efa7023607a7eaec300f42" />
                    <customernumber>123456789</customernumber>
                    <firstName>Robert</firstName>
                    <lastName>Smith</lastName>
                    <born>1970-06-07</born>
                    <patient xsi:type="pptype:PatientDE">
                        <versichertennummer>1234567890</versichertennummer>
                        <versichertenstatus>10001</versichertenstatus>
                        <krankenkasse>Example Health Insurance</krankenkasse>
                        <krankenkasseCode>1234567</krankenkasseCode>
                    </patient>

                    <notes>Mr. Smith is allergic to penicilin.</notes>
                </personData>
            </person>
            
            <prescription>
                <prescriptionId code="prescription-1" />
                
                <prescriptionData>
                    <patientId code="person-1234" />
                    <countrySpecific xsi:type="pptype:PrescriptionDE">
                        <rezeptart>gkv</rezeptart>
                        <gebuehrenfrei>false</gebuehrenfrei>
                        <kinderrezept>false</kinderrezept>
                        <noctu>false</noctu>
                    </countrySpecific>
                </prescriptionData>
            </prescription>

            <operator>
                <displayName>Mr. Doe</displayName>
                <fullName>John Doe</fullName>
                <operatorId code="014a65c7-bf7a-47f6-a542-d085d70060f7" />
                <organization>Example visavia Services Ltd.</organization>
                <organizationId code="95a07944-347d-4f9f-8bea-8b1c2211b799" />
            </operator>

            <total>
                <vat>
                    <vatRate>19</vatRate><!-- 19% VAT -->
                    <price>255</price><!-- EUR2.55 -->
                </vat>
                <total>1594</total><!-- EUR15.94 -->
            </total>

            <!-- The server has added the payment data. -->
            <payment>
                <payment xsi:type="pptype:PaymentCard">
                    <type>Maestro</type>
                </payment>
            </payment>

        </sale>
    </sale:confirmSalePaymentResponse>

The visavia now prints the receipt. It gets the formatted receipt data from the server by invoking createPickupReceipt.

The printer built into the visavia uses a fixed-with font with a maximum of 64 characters per line. The server is therefore configured to generate a receipt of the posps type FixedWidthPrintMarkup with a maximum line width of 64.


createSaleReceipt

Request

<sale:createSaleReceipt>
    <saleId code="example-2" />
</sale:createSaleReceipt>

Response

        <sale:createSaleReceiptResponse>
            <receipts>
                <receipt xsi:type="pptype:FixedWidthPrintMarkup">
<dw>Rowa Pharmacy</dw>
<n>
Rowastra├če 1
53539 Kelberg
www.rowa.de

Receipt No:     1235                           Date: 2008/06/18
Point of sale:     1                           Time: 21:13

Article                      Unit Price       Amount Delivered
---------------------------------------------------------------

CAPTOPRIL 12,5 1A Pharma   100 Pc EUR 0.00        1       1

ASPIRIN DIREKT Kautabl.     20 Pc EUR15.94        2       2

---------------------------------------------------------------

Total net  EUR 15.94
VAT 19%    EUR  2.55      
Payment method: Card

You were served by Mr. Doe.

VAT identification number: DE00000000
</n>
<b>www.mediterminal.de</b>
                </receipt>
            </receipts>
        </sale:createSaleReceiptResponse>

This completes the sale from the point of view of the posps interface. The visavia informs the customer that he can collect his articles, change and receipt, shows a goodbye screen and calls closeSale to finish with the sale.


closeSale

Request

<sale:closeSale>
    <saleId code="example-2"/>
</sale:closeSale>

Response

<sale:closeSaleResponse />