Sie sind auf Seite 1von 295

A Conceptual Schema of Magento

Community Edition v1.4.0.1

Author: Adri Ramirez Papell University: Universitat Politcnica de Catalunya (UPC) BarcelonaTech

ndex

1 Conceptual Schema organitzation 1.1 Structure overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Structural Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Behavioral Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Structural Schema 2.1 Scope . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Schema presentation . . . . . . . . . . . . . . . . 2.3 Schema Overview . . . . . . . . . . . . . . . . . . 2.4 Store Conguration . . . . . . . . . . . . . . . . . . 2.4.1 Stores . . . . . . . . . . . . . . . . . . . . . 2.4.2 Store Conguration . . . . . . . . . . . . . 2.4.3 Currencies . . . . . . . . . . . . . . . . . . 2.4.4 Locations . . . . . . . . . . . . . . . . . . . 2.4.5 Shipping Methods . . . . . . . . . . . . . . 2.4.6 Payment Methods . . . . . . . . . . . . . . 2.4.7 Taxes . . . . . . . . . . . . . . . . . . . . . 2.5 Customers . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Customers . . . . . . . . . . . . . . . . . . 2.5.2 Sessions . . . . . . . . . . . . . . . . . . . 2.6 Store Administration . . . . . . . . . . . . . . . . . 2.6.1 Products . . . . . . . . . . . . . . . . . . . 2.6.2 Product Options . . . . . . . . . . . . . . . 2.6.3 Product Types . . . . . . . . . . . . . . . . 2.6.4 Categories . . . . . . . . . . . . . . . . . . 2.6.5 Attributes . . . . . . . . . . . . . . . . . . . 2.6.6 Attribute Values . . . . . . . . . . . . . . . . 2.6.7 Price Rules . . . . . . . . . . . . . . . . . . 2.7 Additional Activities . . . . . . . . . . . . . . . . . . 2.7.1 Product Tags . . . . . . . . . . . . . . . . . 2.7.2 Product Reviews . . . . . . . . . . . . . . . 2.7.3 Buying Process Information . . . . . . . . . 2.7.4 Newsletters . . . . . . . . . . . . . . . . . . 2.8 Online Catalog . . . . . . . . . . . . . . . . . . . . 2.8.1 Shopping Carts . . . . . . . . . . . . . . . . 2.8.2 Shopping Cart Items . . . . . . . . . . . . . 2.8.3 Shopping cart items of non-simple products 2.8.4 Orders . . . . . . . . . . . . . . . . . . . . . 2.8.5 OrderLines . . . . . . . . . . . . . . . . . . 2.8.6 Invoices . . . . . . . . . . . . . . . . . . . . 2.8.7 Shipments . . . . . . . . . . . . . . . . . . 2.8.8 Refund . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 7 7 8 10 10 11 11 14 14 16 21 24 27 40 52 55 55 58 60 60 79 82 88 91 95 100 105 105 107 109 113 116 116 119 125 131 137 139 143 145

3 Behavioral Schema. Use Case Specication 3.1 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Schema presentation . . . . . . . . . . . . . . . . . . 3.3 Use Case Overview . . . . . . . . . . . . . . . . . . . 3.4 Store Conguration . . . . . . . . . . . . . . . . . . . . 3.4.1 Add a website . . . . . . . . . . . . . . . . . . 3.4.2 Edit a website . . . . . . . . . . . . . . . . . . . 3.4.3 Delete a website . . . . . . . . . . . . . . . . . 3.4.4 Select the default website . . . . . . . . . . . . 3.4.5 Add a store . . . . . . . . . . . . . . . . . . . . 3.4.6 Edit a store . . . . . . . . . . . . . . . . . . . . 3.4.7 Delete a store . . . . . . . . . . . . . . . . . . . 3.4.8 Select the default store of a website . . . . . . 3.4.9 Add an store view . . . . . . . . . . . . . . . . 3.4.10 Edit an store view . . . . . . . . . . . . . . . . 3.4.11 Delete an store view . . . . . . . . . . . . . . . 3.4.12 Select the default store view of a store . . . . . 3.4.13 Select the default language . . . . . . . . . . . 3.4.14 Change the catalog conguration values . . . . 3.4.15 Change the stock conguration values . . . . . 3.4.16 Change the wishlist conguration values . . . . 3.4.17 Change the sales conguration values . . . . . 3.4.18 Change the customer conguration values . . 3.4.19 Change the tax conguration values . . . . . . 3.4.20 Change the shipping conguration values . . . 3.4.21 Change the tell to a friend conguration values 3.4.22 Change the currency conguration values . . . 3.4.23 Change the enabled currencies . . . . . . . . . 3.4.24 Update currency rates . . . . . . . . . . . . . . 3.4.25 Change the geographical conguration values 3.4.26 Change shipping method values . . . . . . . . 3.4.27 Change payment method values . . . . . . . . 3.4.28 Add a customer tax class . . . . . . . . . . . . 3.4.29 Edit a customer tax class . . . . . . . . . . . . 3.4.30 Delete a customer tax class . . . . . . . . . . . 3.4.31 Add a product tax class . . . . . . . . . . . . . 3.4.32 Edit a product tax class . . . . . . . . . . . . . 3.4.33 Delete a product tax class . . . . . . . . . . . . 3.4.34 Add a tax rate . . . . . . . . . . . . . . . . . . . 3.4.35 Edit a tax rate . . . . . . . . . . . . . . . . . . . 3.4.36 Delete a tax rate . . . . . . . . . . . . . . . . . 3.4.37 Add a tax rule . . . . . . . . . . . . . . . . . . . 3.4.38 Edit a tax rule . . . . . . . . . . . . . . . . . . . 3.4.39 Delete a tax rule . . . . . . . . . . . . . . . . . 3.5 Customers . . . . . . . . . . . . . . . . . . . . . . . . 3.5.1 Create a Customer . . . . . . . . . . . . . . . . 3.5.2 Change password . . . . . . . . . . . . . . . . 3.5.3 Change customer details . . . . . . . . . . . . 3.5.4 Administrate address book . . . . . . . . . . . 3.5.5 Edit a customer . . . . . . . . . . . . . . . . . . 3.5.6 Delete a customer . . . . . . . . . . . . . . . . 3.5.7 Show account information . . . . . . . . . . . . 3.5.8 Show address book . . . . . . . . . . . . . . . 3.5.9 Add a customer group . . . . . . . . . . . . . . 2

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

148 148 148 149 154 154 154 154 155 155 155 155 156 156 156 156 157 157 158 158 158 159 159 160 160 160 161 161 162 162 163 163 163 164 164 164 165 165 165 166 166 166 166 167 168 168 168 168 169 169 170 170 170 170

3.5.10 Edit a customer group . . . . . . . . 3.5.11 Delete a customer group . . . . . . 3.5.12 Add an administrator . . . . . . . . . 3.5.13 Edit an administrator . . . . . . . . . 3.5.14 Delete an administrator . . . . . . . 3.5.15 Add a role . . . . . . . . . . . . . . . 3.5.16 Edit a role . . . . . . . . . . . . . . . 3.5.17 Delete a role . . . . . . . . . . . . . 3.5.18 Log In . . . . . . . . . . . . . . . . . 3.5.19 Log Out . . . . . . . . . . . . . . . . 3.5.20 Open session . . . . . . . . . . . . . 3.5.21 Finish session . . . . . . . . . . . . 3.5.22 Change the current Website . . . . . 3.5.23 Change the current Store . . . . . . 3.5.24 Change the current Store View . . . 3.5.25 Change the current Currency . . . . 3.6 Store Administration . . . . . . . . . . . . . 3.6.1 Add a product . . . . . . . . . . . . 3.6.2 Edit a product . . . . . . . . . . . . . 3.6.3 Delete a product . . . . . . . . . . . 3.6.4 Add a product category . . . . . . . 3.6.5 Edit a product category . . . . . . . 3.6.6 Move a product category . . . . . . 3.6.7 Delete a product category . . . . . . 3.6.8 Add an attribute . . . . . . . . . . . 3.6.9 Edit an attribute . . . . . . . . . . . . 3.6.10 Delete an attribute . . . . . . . . . . 3.6.11 Add an attribute set . . . . . . . . . 3.6.12 Edit an attribute set . . . . . . . . . 3.6.13 Delete an attribute set . . . . . . . . 3.6.14 Administrate tier prices of a product 3.6.15 Add a catalog price rule . . . . . . . 3.6.16 Edit a catalog price rule . . . . . . . 3.6.17 Delete a catalog price rule . . . . . . 3.6.18 Add a shopping cart price rule . . . 3.6.19 Edit a shopping cart price rule . . . 3.6.20 Delete a shopping cart price rule . . 3.7 Additional Activities . . . . . . . . . . . . . . 3.7.1 Tag a product . . . . . . . . . . . . . 3.7.2 Add a tag . . . . . . . . . . . . . . . 3.7.3 Edit a tag . . . . . . . . . . . . . . . 3.7.4 Delete a tag . . . . . . . . . . . . . . 3.7.5 Show tags of a customer . . . . . . 3.7.6 Show most popular tags . . . . . . . 3.7.7 Show all tags . . . . . . . . . . . . . 3.7.8 Add a review . . . . . . . . . . . . . 3.7.9 Edit a review . . . . . . . . . . . . . 3.7.10 Delete a review . . . . . . . . . . . . 3.7.11 Add a review property . . . . . . . . 3.7.12 Edit a review property . . . . . . . . 3.7.13 Delete a review property . . . . . . . 3.7.14 Show reviews of a product . . . . . . 3.7.15 Show reviews of a customer . . . . . 3.7.16 Add a product to the wish list . . . . 3

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

171 171 171 172 172 172 173 173 173 174 174 174 175 175 175 175 177 177 177 178 178 178 179 179 179 180 180 180 181 181 182 182 183 183 183 184 184 185 185 185 185 186 186 186 187 187 187 188 188 188 188 189 189 189

3.7.17 Remove a product from the wish list . . . . . . . . . . . 3.7.18 Add a product to the compare list . . . . . . . . . . . . . 3.7.19 Remove a product from the compare list . . . . . . . . . 3.7.20 Share wish list . . . . . . . . . . . . . . . . . . . . . . . 3.7.21 Subscribe to a product price alert . . . . . . . . . . . . . 3.7.22 Subscribe to a product stock alert . . . . . . . . . . . . 3.7.23 Show wish list . . . . . . . . . . . . . . . . . . . . . . . 3.7.24 Show ready to compare products . . . . . . . . . . . . . 3.7.25 Show recently compared products . . . . . . . . . . . . 3.7.26 Show recently viewed products . . . . . . . . . . . . . . 3.7.27 Show compare . . . . . . . . . . . . . . . . . . . . . . . 3.7.28 Add a newsletter template . . . . . . . . . . . . . . . . . 3.7.29 Edit a newsletter template . . . . . . . . . . . . . . . . . 3.7.30 Delete a newsletter template . . . . . . . . . . . . . . . 3.7.31 Add a newsletter . . . . . . . . . . . . . . . . . . . . . . 3.7.32 Edit a newsletter . . . . . . . . . . . . . . . . . . . . . . 3.7.33 Subscribe to the newsletter . . . . . . . . . . . . . . . . 3.7.34 Unsubscribe from the newsletter . . . . . . . . . . . . . 3.7.35 Delete a newsletter subscription . . . . . . . . . . . . . 3.7.36 Unsubscribe a newsletter subscription . . . . . . . . . . 3.7.37 Show shopping cart . . . . . . . . . . . . . . . . . . . . 3.7.38 Download a product . . . . . . . . . . . . . . . . . . . . 3.7.39 Show downloadable products of a customer . . . . . . . 3.7.40 Tell to a friend . . . . . . . . . . . . . . . . . . . . . . . 3.7.41 View product information . . . . . . . . . . . . . . . . . 3.7.42 Search products . . . . . . . . . . . . . . . . . . . . . . 3.7.43 Show the best purchased products . . . . . . . . . . . . 3.7.44 Reset the temporal information . . . . . . . . . . . . . . 3.8 Online catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8.1 Place an order . . . . . . . . . . . . . . . . . . . . . . . 3.8.2 Checkout an order with multiple addresses . . . . . . . 3.8.3 Add an order . . . . . . . . . . . . . . . . . . . . . . . . 3.8.4 Cancel an order . . . . . . . . . . . . . . . . . . . . . . 3.8.5 Hold an order . . . . . . . . . . . . . . . . . . . . . . . . 3.8.6 Unhold an order . . . . . . . . . . . . . . . . . . . . . . 3.8.7 Reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8.8 Add a gift message to a placed order . . . . . . . . . . 3.8.9 Print an Order . . . . . . . . . . . . . . . . . . . . . . . 3.8.10 Send order information by email . . . . . . . . . . . . . 3.8.11 Show previous orders of a customer . . . . . . . . . . . 3.8.12 Add an invoice . . . . . . . . . . . . . . . . . . . . . . . 3.8.13 Register an invoice payment . . . . . . . . . . . . . . . 3.8.14 Cancel an invoice . . . . . . . . . . . . . . . . . . . . . 3.8.15 Add a shipment . . . . . . . . . . . . . . . . . . . . . . . 3.8.16 Add a refund . . . . . . . . . . . . . . . . . . . . . . . . 3.8.17 Cancel a refund . . . . . . . . . . . . . . . . . . . . . . 3.8.18 Add a comment to an order, invoice, shipment or refund. 3.9 Store Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.9.1 Show the sales report . . . . . . . . . . . . . . . . . . . 3.9.2 Show the tax report . . . . . . . . . . . . . . . . . . . . 3.9.3 Show the shipping report . . . . . . . . . . . . . . . . . 3.9.4 Show the invoices report . . . . . . . . . . . . . . . . . 3.9.5 Show the refunds report . . . . . . . . . . . . . . . . . . 3.9.6 Show the coupon codes report . . . . . . . . . . . . . . 4

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

190 190 190 191 191 191 191 192 192 192 192 193 193 193 194 194 194 195 195 195 195 196 196 196 197 197 197 197 199 199 201 202 204 204 204 205 205 205 206 206 206 207 207 207 208 209 209 210 210 210 210 210 211 211

3.9.7 3.9.8 3.9.9 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.20 3.9.21 3.9.22

Show the products in carts report . . . . . . . . . Show the abandoned carts report . . . . . . . . Show the bestseller products report . . . . . . . Show the ordered products report . . . . . . . . Show the most viewed products report . . . . . . Show the stock of products report . . . . . . . . Show the downloads report . . . . . . . . . . . . Show the new customer accounts report . . . . . Show the customers by orders total report . . . . Show the customers by number of orders report Show the customer reviews report . . . . . . . . Show the product reviews report . . . . . . . . . Show the tags by customer report . . . . . . . . Show the tags by product report . . . . . . . . . Show the popular tags report . . . . . . . . . . . Show the search terms report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

211 212 212 212 213 213 213 214 214 214 214 215 215 215 216 216 217 217 218 219 226 226 226 227 227 229 229 230 230 231 232 233 234 234 235 236 237 238 239 239 240 240 241 241 242 243 243 247 252 253 253 255 257

4 Behavioral Schema. Events Specication 4.1 Scope . . . . . . . . . . . . . . . . . . . 4.2 Schema presentation . . . . . . . . . . 4.3 Events Overview . . . . . . . . . . . . . 4.4 Store Conguration . . . . . . . . . . . . 4.4.1 SetDefaultWebsite . . . . . . . . 4.4.2 SetDefaultStoreOfWebsite . . . . 4.4.3 SetDefaultStoreViewOfStore . . 4.4.4 SetDefaultLanguage . . . . . . . 4.5 Customers . . . . . . . . . . . . . . . . 4.5.1 CreateCustomer . . . . . . . . . 4.5.2 PasswordChange . . . . . . . . 4.5.3 EditCustomerDetails . . . . . . . 4.5.4 NewCustomerAddress . . . . . . 4.5.5 DeleteCustomerAddress . . . . . 4.5.6 DefaultDeliveryAddressChange . 4.5.7 DefaultBillingAddressChange . . 4.5.8 EditCustomerAddress . . . . . . 4.5.9 LogIn . . . . . . . . . . . . . . . 4.5.10 RestorePreviousShoppingCart . 4.5.11 RestorePreviousProductLists . . 4.5.12 LogOut . . . . . . . . . . . . . . 4.5.13 SaveCurrentProductLists . . . . 4.5.14 NewSession . . . . . . . . . . . 4.5.15 DeleteSession . . . . . . . . . . 4.5.16 SetCurrentWebsite . . . . . . . . 4.5.17 SetCurrentStore . . . . . . . . . 4.5.18 SetCurrentStoreView . . . . . . 4.5.19 SetCurrentCurrency . . . . . . . 4.6 Store Administration . . . . . . . . . . . 4.6.1 NewProduct . . . . . . . . . . . . 4.6.2 EditProduct . . . . . . . . . . . . 4.6.3 DeleteProduct . . . . . . . . . . 4.6.4 MoveCategory . . . . . . . . . . 4.6.5 NewAttribute . . . . . . . . . . . 4.6.6 EditAttribute . . . . . . . . . . . . 4.6.7 DeleteAttribute . . . . . . . . . . 5

4.7 Additional Activities . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.1 NewReview . . . . . . . . . . . . . . . . . . . . . . . . . 4.7.2 NewAdministratorReview . . . . . . . . . . . . . . . . . 4.7.3 AddProductToWishlist . . . . . . . . . . . . . . . . . . . 4.7.4 AddCommentToWishlistItem . . . . . . . . . . . . . . . 4.7.5 RemoveCommentFromWishlistItem . . . . . . . . . . . 4.7.6 RemoveProductFromWishlist . . . . . . . . . . . . . . . 4.7.7 AddProductToCompareList . . . . . . . . . . . . . . . . 4.7.8 RemoveProductFromCompareList . . . . . . . . . . . . 4.7.9 SingUpForPriceAlert . . . . . . . . . . . . . . . . . . . . 4.7.10 SingUpForStockAlert . . . . . . . . . . . . . . . . . . . . 4.7.11 SignUpForNewsletter . . . . . . . . . . . . . . . . . . . 4.7.12 SignDownFromNewsletter . . . . . . . . . . . . . . . . . 4.7.13 TellToAFriendUsed . . . . . . . . . . . . . . . . . . . . . 4.7.14 ProductViewed . . . . . . . . . . . . . . . . . . . . . . . 4.7.15 ResetTemporalInfo . . . . . . . . . . . . . . . . . . . . . 4.8 Online catalog . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.1 ProductViewed . . . . . . . . . . . . . . . . . . . . . . . 4.8.2 AddProductToShoppingCart . . . . . . . . . . . . . . . . 4.8.3 UpdateShoppingCart . . . . . . . . . . . . . . . . . . . 4.8.4 ApplyCouponCode . . . . . . . . . . . . . . . . . . . . . 4.8.5 OrderConrmation . . . . . . . . . . . . . . . . . . . . . 4.8.6 DuplicateAccount . . . . . . . . . . . . . . . . . . . . . . 4.8.7 NewAdministrationShoppingCart . . . . . . . . . . . . . 4.8.8 AddProductToShoppingCart . . . . . . . . . . . . . . . . 4.8.9 ChangeCurrencyOfAdministrationShoppingCart . . . . 4.8.10 ChangeEMailAndGroupOfAdministrationShoppingCart . 4.8.11 ApplyCouponCode . . . . . . . . . . . . . . . . . . . . . 4.8.12 AddProductToShoppingCart . . . . . . . . . . . . . . . . 4.8.13 AddGiftMessage . . . . . . . . . . . . . . . . . . . . . . 4.8.14 AddGiftMessageToItem . . . . . . . . . . . . . . . . . . 4.8.15 OrderConrmation . . . . . . . . . . . . . . . . . . . . . 4.8.16 DeleteAdministrationShoppingCart . . . . . . . . . . . . 4.8.17 CancelOrder . . . . . . . . . . . . . . . . . . . . . . . . 4.8.18 HoldOrder . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.19 UnholdOrder . . . . . . . . . . . . . . . . . . . . . . . . 4.8.20 Reorder . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.21 AddInvoice . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.22 PayInvoice . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.23 CancelInvoice . . . . . . . . . . . . . . . . . . . . . . . 4.8.24 AddShipment . . . . . . . . . . . . . . . . . . . . . . . . 4.8.25 AddRefund . . . . . . . . . . . . . . . . . . . . . . . . . 4.8.26 CancelRefund . . . . . . . . . . . . . . . . . . . . . . . 4.8.27 AddComment . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

258 258 259 260 261 261 262 263 264 264 265 266 267 268 269 270 271 271 272 273 274 274 277 278 278 280 280 281 281 283 283 284 286 287 287 288 288 289 290 291 291 292 293 294

Conceptual Schema organitzation


Chapters 2, 3 and 4 describe the Magentos conceptual Schema in UML / OCL notation. Due to its size, the schema must be organized and divided in parts, facilitating its comprensibility. This chapter presents the organizative structure that has been used to document Magentos Conceptual Schema. Section 1.1 presents a global view, which is detailed in sections 1.2 and 1.31 .

1.1 Structure overview


Magentos Conceptual Schema is organised in the same way as in osCommerce Conceptual Schema (see ?). Its structure can be divided in two parts: structural and behavioral (sub)schemas. Structural Schema presents the static knowledge of the system: entities, properties of those entities and constraints. Those concepts are represented in UML diagrams and OCL expressions. Behavioral Schema describes the features that the system offers to its users, also known as its dynamic behaviour. The description is made by Use Cases, which are specied in natural language and related to the main system Events. Events effects and restrictions are specied in OCL.

1.2 Structural Schema


A structural schema consists of a taxonomy of entity types (a set of entity types with their generalization/specialization relationships and the taxonomic constraints), a set of relationship types (either attributes or associations), the cardinality constraints of the relationship types and a set of other constraints formally dened in OCL. Entity and relationship types may be base or derived. The population of the base entity and relationship types is explicitly represented in the Information Base (IB). If they are derived, there is a formal derivation rule in OCL that denes their population in terms of the population of other types. Magentos Structural Schema can be considered a large schema. Therefore, it cant be represented together, so it has been divided in several sub-schemas that group related concepts. Sub-schemas are interrelated and, as a whole, they perform the complete Structural Schema
1 Some

denitions in this chapter are citations of ??

and represent the knowledge about the analysed domain. In order to facilitate its comprensibility, sub-schemas have been classied in ve groups. First, we present three simplied diagrams, that contain only the main entities and relationships of the system. Afterwards, the set of sub-schemas is detailed. In order to facilitate schemas readability and comprensibility, each sub-schema is presented in the following format:
I

Sub-schemas Name Overview: brief explanation about the knowledge represented by the sub-schema. Schema Diagram: UML class diagram specifying the domain knowlege represented by the sub-schema. Entities that are specied in other sub-schemas but have relationships with entities specied here are shown in white colour, hidding its attributes. Sometimes, the UML sub-schemas diagram must be separated in two or more pages due to document formatting. Operations: auxiliar operations used in constraints and derivation rules. Derivation Rules: derivation rules, specied in OCL operations. Constraints: integrity constraints that have not been expressed graphically. All of them are specied as boolean OCL operations. Description: sub-schemas detailed description in natural language. Sometimes, it can be followed by an State-Chart Diagram to facilitate its understanding.

1.3 Behavioral Schema


The behavioral schema consists of a set of use cases and event types. Event types are modelized as UML classes with the <<Event>> stereotype. In general, there are three kinds of event types: domain events, action requests and queries. Domain events have characteristics, constraints and effects. The characteristics of an event are the set of relationships (attributes or associations) in which it participates. Each event type has an operation called effect() that gives the effect of an event occurrence. The characteristics of the event are used as input parameters for the effect() operation. We dene the effect by the postcondition of the operation. Both the event constraints and the postcondition are specied in OCL. The postcondition denes the state of the IB after the event occurrence. Therefore, the effect of a domain event is a state that satises the postcondition and all IB constraints. Note that the OCL expressions used in constraints, derivation rules and pre/post conditions are without sideeffects. These expressions are evaluated over the IB and their evaluation cannot change the IB. Behavioral schema presents use case specication in natural language, following the format specied below:
I

Use Case Name Primary Actor: main use case actor. Precondition: conditions that must be satised to execute the use case, specied in natural language. Trigger: action that initiates the use case. Main Success Scenario: an specication of the interaction between the system and the use case actors, specied in a numered sequence of sentences in natural language. 8

Extensions: specication of alternative interactions to the main scenario. Its rst number indicates the stage of the main scenario where the extension starts.

In some stages of scenario specication (main or extensions), the main system Events are invoked, with the following syntaxis: [-> EventName] Those Events are specied in chapter 4, using de format detailed below:
I

Event Name Event Characteristics: the set of relationships (attributes or associations) in which it participates and are used as input parameters for the effect() operation. Initial Integrity Constraints: conditions that must be satised before the Event starts. They are specied in OCL. Effect: effect that productes the Events execution in the information base. It is specied in OCL.

Structural Schema
In this chapter we develop the structural schema of the Magento information system. Section 2.1 denes the scope of the schema elicitation, while section 2.2 describes the way the schema is presented. Section 2.3 presents an overview of the whole schema, which is detailed in section 2.4 and furthermore.

2.1 Scope
A conceptual schema represents the knowledge that a system needs to know about its domain, and about the functions it has to perform ?. Thus, knowledge related to the way the system is presented, or technical aspects that depend on the technologies it is implemented are analysed in further stages of the development process. When eliciting this schema from Magento, those aspects have been identied and not included in the conceptual schema. More precisely, they refer to the following aspects:
I

Design and presentation Conguration of the integration with external systems: Magento can communicate to external systems such as Pay Pal, Google or Visa and conguration parameters are needed. Static web pages management: by default, Magento generates all its web pages depending on the state of its information base, but it offers administrators to include their own static pages too. Other technical aspects: CSS, Javascript or RSS conguration. Advanced conguration: system time-outs, backups, compilation, URL redirection and more.

Furthermore, the purpose of this project is to describe the conceptual schema of an e-commerce system, Magento. Thus, those knowledge that does not characterize the buying activity has not been included in the schema:
I

Search engine: included in Magento, allows users searching products by keywords and manages a history of the last and more used search terms.

10

Finally, Magento has a huge list of extensions that can be added to the core system. Each extension needs its own knowledge to perform its functions, and the available extensions never cease to change. The conceptual schema specied does not represent the knowledge need by any of those extensions.

2.2 Schema presentation


The main purpose of the Magentos structural schema is to provide a description of the conceptualization of the Magentos domain. The structural schema is too large to be presented together. Therefore, this chapter begins with three UML general view diagrams with the most important conceptual entity types and their relationship types. Next, the whole schema is structured in several diagrams of greater detail in order to make it more understandable. Each diagram corresponds to a part of the whole detailed schema and groups together related concepts which can be seen as a set of knowledge about the information system. Entities which appear in a structural schema fragment but are fully specied in other conceptual grouping diagrams are drawn without showing their attributes. Each fragment of the whole structural schema diagram is represented in UML and is introduced by a brief textual overview. Derived types and integrity constraints are specied in OCL. The structural schema specication uses standard UML with some extensions (specication of derived types and constraints by OCL operations, constant and permanent stereotypes, etc.) explained in ?.

2.3 Schema Overview


Three UML diagrams are used to represent a simplied conceptual schema of the Magentos domain. More details about each concept are given in the next section, where the whole schema is fully specied.

Figure 2.1: Store Conguration and Customers Schema Overview

11

Store Conguration Subschemas classied into this group describe the core structure of the Magento System: Websites, Stores and StoreViews. Those three concepts act as different granularity levels when conguring several system properties. For each of them, the System Administrator can dene the desired conguration about Shipping and Payment methods, Languages, Currencies, Locations, Taxes and more (see g. 2.1). Customers Magento saves information about Customers, which are relied to a Website. Each Customer can be associated to one or more Addresses. Any use of the system can be conceptually represented by a Session. A Session can be relied to a registered Customer or it can be anonymous (see g. 2.1).

Figure 2.2: Store Administration and Additional Activities Schema Overview

Store Administration The system mantains information about a catalog of Products, whose properties can be dened at three levels of granularity. Products are classied in Categories. Attributes can be dened for products by the Store Administrator. For each pair Attribute - Product, the Store Administrator can assign an AttributeValue at any granularity level. In addition, Options can be also added to products. In that case, its value is choosen by Customers when purchasing the product (see g. 2.2). Additional Activities Magento saves information about the activities performed by customers when they navigate throught the catalog and purchase products. Furthermore, the system offers other features to users such as adding Tags and Reviews to products, or suscribing to a Newsletter (see g. 2.2).

12

Figure 2.3: Online Catalog Schema Overview Online Catalog Users that navigate throught the catalog can add the Products they want to buy to a ShoppingCart. The purchase of a Product in a ShoppingCart is represented by a ShoppingCartItem. Each ShoppingCart is asosociated to an Store View. Depending on several conditions, PriceRules can be associated to a ShoppingCartItem, decrementing its price (see g. 2.3).

13

2.4 Store Conguration


2.4.1
I

Stores

Overview
Magento allows multi-store support. It denes a hierarchy of Websites, Stores and Storeviews.

Schema Diagram

Constraints
[1] Websites are identied by its code.

14

Context Website :: isIdentiedByItsCode() : Boolean body: Website.allInstances() -> isUnique(code) [2] Store are identied by its name.

Context Store :: isIdentiedByItsName() : Boolean body: Store.allInstances() -> isUnique(name) [3] StoreViews are identied by its code and also by its name.

Context StoreView :: isIdentiedByItsCodeAndName() : Boolean body: StoreView.allInstances() -> isUnique(code) and StoreView.allInstances() -> isUnique(name) [4] Each language is identied by its name.

Context Language :: isIdentiedByItsName() : Boolean body: Language.allInstances() -> isUnique(name) [5] Each time zone is identied by its name.

Context TimeZone :: isIdentiedByItsName() : Boolean body: TimeZone.allInstances() -> isUnique(name)

Description
Magento is able to manage multiple websites and stores. It organizes them in a hierarchy of Websites, Stores and Store Views. The Website is the top-level structure and it consists of stores. Websites save the information about customers, shopping carts and orders, as shown in the next sections. This information is shared within the stores and store views of the website. Stores are the middle level structure. Some product attributes and categories are dened at the store level and shared with all the store views of the store. A Store View is a way of presenting a store. In most cases, different storeViews are used to show the same store in different languages. We can also dene two store views from the same store in the same language, but oriented to different costumer segments. Store views are identied by its name and code. When customers access the system, they access to the default website. When customers access a website, they access to its default store. When customers access a store, its default store view is shown.

15

2.4.2
I

Store Conguration

Overview
Magento allows the store administrator to specify several congurations to affect the way that the system works.

Schema Diagram

16

Constraints
[1] The catalog price scope should be Global or Website.

Context CatalogConguration :: hasACorrectPriceScope() : Boolean body: not (self.catalogPriceScope = Scope::StoreView) [2] The catalog price scope should be Website or Store View.

Context CatalogCongurationInWebsite :: hasACorrectRecentlyViewedAndComparedProductsScope() : Boolean body: not (self.recentlyViewedAndComparedProductsScope = Scope::Global)

17

[3]

The share account scope should be Global or Website.

Context CustomerConguration :: hasACorrectShareAccountScope() : Boolean body: not (self.shareAccountScope = Scope::StoreView) [4] If the tax is applied after discount, there is no denition about if discounts are applied including taxes or not. Context TaxCongurationInWebsite :: denesTheApplyDiscountMethodWhenItsNeeded() : Boolean body: (self.methodRespectingDiscount = TaxRespectingDiscountsMethod::TaxAfterDiscount) = (self.applyDiscountIncludingTax -> isEmpty()) [5] The the default customer group should not be the group named NotLoggedIn.

Context CustomerCongurationInStoreView :: doesNotDeneTheNotLoggedInGroupAsDefault() : Boolean body: self.defaultCustomerGroup.name <> NotLoggedIn

Description
Magentos conguration is organised in several groups. For each group, some properties are dened at the global level, others at the website level and others at the store view level. The Catalog Conguration manages most of the properties about products: catalogPriceScope: denes the scope the product prices will be shared at. allowStockAlert: determines if the customers can indicate the system to notify them when a selected product which is out of stock comes back in stock. allowGuestsToWriteReviews: allows not registered users to write reviews for a product. recentlyViewedComparedProductsScope: denes the scope the recently viewed and comparet list will be shared at. allowDownloadBeforeOrderIsComplete: allows downloadable products to be downloaded before an order is already paid. allowGuestCheckoutForDownloadableItems: allows not registered users to purchase downloadable products. maximumDownloadCount: the maximum of times a downloadable product can be downloaded. allowPriceAlert: determines if the customers can indicate the system to notify them when a selected product changes its price. numberOfRecentlyComparedProductsSaved: that will be saved in the recently compared products list. numberOfRecentlyViewedProductsSaved: that will be saved in the recently viewed products list. The Stock Conguration manages the product stock properties. The last ve can be redened for each individual product. decreaseStockWhenOrderIsPlaced: determines whether the quantity of a product will automatically decrease when an order that purchases this product is placed. setItemInStockWhenOrderIsCancelled: determines whether the quantity of a product will automatically be re-increased when an order that purchases this product is cancelled.

18

displayOutOfStockProducts: determines whether products Out Of Stock are displayed to customers. qtyToBecomeOutOfStock: determine at which quantity the availability of the item will switch from In Stock to Out of Stock. minQtyAllowedInShoppingCart: the minimum amount the customer is required to purchase of each product in an order. maxQtyAllowedInShoppingCart: the maximum amount the customer is allowed to purchase of each product in an order. notifyForQuantityBelow: when a stock of any product goes below this level, Magento will automatically notify the store admin. backOrderPolicy: determines if customers are allowed to purchase more quantity than is available or not and, if yes, if they are notied when they place an order with unavailable quantities. The Wishlist Conguration allows to set if wishlists are or not allowed in a website. The Sales Conguration denes: allowGiftMessageForOrders: allows customers to add a gift message to its orders. allowGiftMessageForOrderLines: allows customers to add a gift message to a product they have ordered. The Customer Conguration denes: shareAccountScope: denes the scope the customer accounts will be shared at. defaultCustomerGroup: the customer group that a customer will be assigned by default when it is created. The Tax Conguration denes how taxes are calculated and when are they shown to users: shippingTax: this tax will be applied to shipping costs. method: determines wether the tax amount is calculated for each item, for each order line or for all the order. This can make the nal tax amount vary due to decimal truncation. usedAdress: the adress that will be use to calculate the applicable taxes. See taxes and orders sections. methodRespectingDiscount: determines whether the taxes are applied before or after discounts. applyDiscountIncludingTax: if taxes are applied before discounts, determines whether an eventual discount is applied taking into account the tax amount. applyTaxOnCustomPriceIfAvailable: when a product is sold to a customer with a custom price, determines if taxes are applied to the new or the original price. displayShippingPriceWithTax: determines if shipping costs are shown to customers with or without taxes. displayProductPriceWithTax: determines if product prices are shown to customers with or without taxes. The Shipping Conguration manages the following information: shippingOrigin: the postal area from where the shipments will be sent.

19

allowShippingToMultipleAdresses: determines whether it is allowed to ship products from the same order to different adresses. When an Order with multiple shipping addresses is saved, it will split into multiple Orders because only one shipping address per order is allowed. mawQtyAllowedForMultipleAdresses: maximum quantity that a customer can enter in the for each item in a multiple adresses checkout. The Tell to a friend Conguration denes: status: enables or disables all customers, including guests, to automatically send mails with information about a product. guestStatus: enables or disables not registered customers (guests) to automatically send mails with information about a product. maxUsesPerHour: the maximum of times a customer can use the tell to a friend feature per hour. The Currency Conguration denes several currency properties that will be commented in the Currency section. Similarly, the Locations Conguration will be commented in the Locations section.

20

2.4.3
I

Currencies

Overview
Magento is able to work with different currencies.

Schema Diagram

Derivation Rules
[1] CurrencyCongurationInWebsite :: baseCurrency is the websites base currency, if it is dened, or the general systems base currency otherwise. Context CurrencyCongurationInWebsite :: baseCurrency : Currency body:

21

if self.redenedBaseCurrency -> notEmpty() and CatalogConguration.catalogPriceScope = Scope::Website then self.redenedBaseCurrency else CurrencyConguration.genericBaseCurrency endif

[2] CurrencyCongurationInStoreView :: allowedCurrency are the store views allowed currencies, if it is dened. If not, the websites allowed currencies or the generic allowed currencies. Context CurrencyCongurationInStoreView :: allowedCurrency : Currency body: if self.redenedAllowedCurrency -> notEmpty() then self.redenedAllowedCurrency else if self.storeView.store.website.currencyCongurationInWebsite.redenedAllowedCurrency -> notEmpty() then self.storeView.store.website.currencyCongurationInWebsite.redenedAllowedCurrency else CurrencyConguration.genericAllowedCurrency endif [3] CurrencyCongurationInStoreView :: defaultCurrency is the store views default currency, if it is dened. If not, the websites default currency or the generic default currency.. Context CurrencyCongurationInStoreView :: defaultCurrency : Currency body: if self.redenedDefaultCurrency -> notEmpty() then self.redenedDefaultCurrency else if self.storeView.store.website.currencyCongurationInWebsite.redenedDefaultCurrency > notEmpty() then self.storeView.store.website.currencyCongurationInWebsite.redenedDefaultCurrency else CurrencyConguration.genericDefaultCurrency endif

Constraints
[1] Each currency is identied by its name.

Context Currency :: isIdentiedByItsName() : Boolean body: Currency.allInstances() -> isUnique(name) [2] The base currency of a website is enabled.

Context CurrencyCongurationInWebsite :: hasABaseCurrencyWhichIsEnabled() : Boolean body: self.baseCurrency.status = Status::Enabled [3] Only enabled currencies can be used in a Store View.

Context CurrencyCongurationInStoreView :: allowsOnlyToUseEnabledCurrencies() : Boolean body: self.allowedCurrency -> forAll ( ac | ac.status = Status::Enabled ) [4] Each currency allowed in a store view has a rate to relate it with the base currency of the website the store view belongs to. Context CurrencyCongurationInStoreView :: hasTheNecessaryCurrencyRates() : Boolean body: self.allowedCurrency -> forAll ( ac | ac.baseCurrency -> includes(self.storeView.store.website.baseCurrency) ) [5] The currency rate should be 1 if both currencies are the same.

Context CurrencyRate :: isOneIfCurrenciesAreEquals() : Boolean body: self.baseCurrency = self.currency implies self.rate = 1

22

Description
Magento has a predened set of currencies. Administrators can enable or disable them. Each website has a base currency. The priced orders placed in this website are stored in the base currency. A generic base currency can be dened for all websites and it can be redened specically for a website. In each store view, the costumer will be able to see the monetary amounts in any of its allowed currencies. By default, those amounts will be shown in the default currency. Also a generic set of allowed currencies and a generic default currency can be dened for all store views and redened specically at the website or store view level. A conversion rate should be dened between each allowed currency and the base currency of its website. The rate is dened as follows: X base currency = rate * X allowed currency.

23

2.4.4
I

Locations

Overview
Magento saves information about customer adresses.

Schema Diagram

Derivation Rules
[1] LocationsCongurationInStoreView :: allowedCountry are the store views allowed countries, if dened. If not, the websites allowed countries or the generic allowed countries. Context LocationsCongurationInStoreView :: allowedCountry : Set(Country) body: if self.redenedAllowedCountry -> notEmpty() then self.redenedAllowedCountry else if self.storeView.store.website.locationsCongurationInWebsite.redenedAllowedCountry > notEmpty()then self.storeView.store.website.locationsCongurationInWebsite.redenedAllowedCountry else LocationsConguration.genericAllowedCountry endif

Constraints
[1] Countries are identied by its name.

24

Context Country :: isIdentiedByItsName() : Boolean body: Country.allInstances() -> isUnique(name) [2] Zones are identied by its name and country.

Context Zone :: isIdentiedByItsNameAndCountry() : Boolean body: Zone.allInstances() -> isUnique(Setname,country) [3] Municipalities are identied by its name and country.

Context Municipality :: isIdentiedByItsNameAndCountry() : Boolean body: Municipality.allInstances() -> isUnique(Setname,country) [4] Postal areas are identied by its postal code and country.

Context PostalArea :: isIdentiedByItsPostalCodeAndCountry() : Boolean body: PostalArea.allInstances() -> isUnique(SetpostalCode,municipality.country) [5] If the address country has zones, the address is also associated to a zone of this country.

Context Address :: hasACorrectZoneIfItIsNeeded() : Boolean body: self.country.zone -> notEmpty() implies (self.zone -> notEmpty() and self.country = self.zone.country) [6] If the country the municipality is part of has zones, the municipality is also associated to a zone of this country. Context Municipality :: hasACorrectZoneIfItIsNeeded() : Boolean body: self.country.zone -> notEmpty() implies (self.zone -> notEmpty() and self.country = self.zone.country) [7] If the country where an adress is located forces to specify a postal area, the address is associated to one postal area. Context Adress :: hasAPostalAreaIfItIsNeeded() : Boolean body: self.country.postalCodeIsMandatory implies self.postalArea -> notEmpty() [8] The postal area of an address belongs to the municipality of that address.

Context Adress :: hasACorrectPostalArea() : Boolean body: self.municipality.postalArea -> includes( self.postalArea ) [9] The municipality of an address belongs to the country and zone (if the zone is dened) of that address. Context Adress :: hasACorrectMunicipality() : Boolean body: self.country.municipality -> includes( self.municipality ) and self.zone -> notEmpty() implies self.zone.municipality -> includes ( self.municipality ) [10] If an adress is related to a zone, the zone belongs to the country of that address.

Context Adress :: hasACorrectZone() : Boolean body: self.country.zone -> includes( self.zone )

Description
Magento allows creating customer adresses. Adresses specify where the orders will be billed or delivered. Each adress consists of: 25

rstName middleName lastName namePrex nameSufx company streetAdress telephone fax A Postal Area represents a geographical zone which shares the same postal code. A Municipality is an administrative entity composed of a clearly dened territory and its population and denotes a city, town or village. Each municipality belongs to a Country. When a costumer creates a new adress, he will be able to choose only between the countries allowed in the current store view. Zones are states or provinces of a country. It is important to note that there can be countries with no zones dened.

26

2.4.5
I

Shipping Methods

Overview
The system can operate with different shipping methods.

Schema Diagram

27

28

Operations
[1] context FlatRateInWebsite def: calculateCost (purchasedProducts : Set(OrderLine), delivery : Address) : Money = if self.method=FlatRateMethod::None then 0 else if self.method = FlatRateMethod::PerOrder then

29

self.cost else self.cost * ( purchasedProducts.quantity -> sum() ) endif endif [2] context TableRateInWebsite def: calculateCost (purchasedProducts : Set(OrderLine), delivery : Address) : Money = let usedValue:Decimal = if self.method=TableRateMethod::Weight then lines -> collect ( l | Product.allInstances() -> any(p|l.productSku=p.sku).productInStoreView -> any(piw|piw.storeView=l.order.storeView).weight * l.quantity ) -> sum() else if self.method=TableRateMethod::Price then purchasedProducts.total -> sum() else purchasedProducts.quantity -> sum() endif endif in let underValueItems:Set(TableRateItem) = self.item -> select ( i | i.number < usedValue ) in self.tableRateItem -> any ( i | underValueItems -> forAll ( uvi | uvi.number <= i.number )).cost [3] context FreeShippingInWebsite def: calculateCost (purchasedProducts : Set(OrderLine), delivery : Address) : Money = 0 [4] context ExternalShippingMethodInWebsite def: Set(OrderLine), delivery : Address) : Money This operation calls an external service. calculateCost (purchasedProducts :

Derivation Rules

[1] ShippingMethodInStoreView :: title is the redenedStatus. If theres no redenition at that level, it is the nearest upper redened value. Context ShippingMethodInStoreView :: title : String body: if self.redenedTitle -> notEmpty() then self.redenedTitle else if self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedTitle -> notEmpty() then self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedTitle else self.shippingMethod.genericTitle endif endif [2] InternalShippingMethodInStoreView :: methodName is the redened method name. If theres no redenition at that level, it is the nearest upper redened value. Context InternalShippingMethodInStoreView :: methodName : String body: if self.redenedMethodName -> notEmpty() then self.redenedMethodName else if self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedMethodName -> notEmpty() then self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedMethodName else self.shippingMethod.genericMethodName

30

endifendif [3] ShippingMethodInStoreView :: errorMessage is the redenedErrorMessage. If theres no redenition at that level, it is the nearest upper redened value. Context ShippingMethodInStoreView :: errorMessage : String body: if self.redenedErrorMessage -> notEmpty() then self.redenedErrorMessage elseif self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedErrorMessage -> notEmpty() then self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedErrorMessage else self.shippingMethod.genericErrorMessage endif [4] ShippingMethodInWebsite :: allowedCountry the redenedAllowedCountry. If theres no redenition at the website level, it is the generic value. Context ShippingMethodInWebsite :: allowedCountry : Set(Country) body: if self.redenedAllowedCountry -> notEmpty() then self.redenedAllowedCountry else self.shippingMethod.genericAllowedCountry endif [5] ShippingMethodInWebsite :: status is the redenedStatus. If theres no redenition at the website level, it is the generic value. Context ShippingMethodInWebsite :: status : Status body: if self.redenedStatus -> notEmpty() then self.redenedStatus else self.shippingMethod.genericStatus endif [6] ShippingMethodInWebsite :: showIfNotApplicable is the redenedShowIfNotApplicable. If theres no redenition at the website level, it is the generic value. Context ShippingMethodInWebsite :: showIfNotApplicable : Boolean body: if self.redenedShowIfNotApplicable -> notEmpty() then self.redenedShowIfNotApplicable else self.shippingMethod.genericShowIfNotApplicable endif [7] ShippingMethodInWebsite :: handlingCalculatingMethod is the redenedHandlingCalculatingMethod. If theres no redenition at the website level, it is the generic value. Context ShippingMethodInWebsite :: handlingCalculatingMethod : PriceCalculatingMethod body: if self.redenedHandlingCalculatingMethod -> notEmpty() then self.redenedHandlingCalculatingMethod else self.shippingMethod.genericHandlingCalculatingMethod endif [8] ShippingMethodInWebsite :: handlingFee is the redenedHandlingFee. If theres no redenition at the website level, it is the generic value. Context ShippingMethodInWebsite :: handlingFee : Decimal body:

31

if self.redenedHandlingFee -> notEmpty() then self.redenedHandlingFee else self.shippingMethod.genericHandlingFee endif [9] FlatRateInWebsite :: method is the redenedMethod. If theres no redenition at the website level, it is the generic value. Context FlatRateInWebsite :: method : FlatRateMethod body: if self.redenedMethod -> notEmpty() then self.redenedMethod else self.atRate.genericMethod endif [10] FlatRateInWebsite :: cost is the redenedCost. If theres no redenition at the website level, it is the generic value. Context FlatRateInWebsite :: cost : Money body: if self.redenedCost -> notEmpty() then self.redenedCost else self.atRate.genericCost endif [11] TableRateInWebsite :: items is the redenedItems. If theres no redenition at the website level, it is the generic value. Context TableRateInWebsite :: items : ShippingTableItem body: if self.redenedItems -> notEmpty() then self.redenedItems else self.tableRate.genericItems endif [12] TableRateInWebsite :: method is the redenedMethod. If theres no redenition at the website level, it is the generic value. Context TableRateInWebsite :: method : ShippingTableMethod body: if self.redenedMethod -> notEmpty() then self.redenedMethod else self.tableRate.genericMethod endif [13] TableRateInWebsite :: includeVirtualProducts is the redenedIncludeVirtualProducts. theres no redenition at the website level, it is the generic value. Context TableRateInWebsite :: includeVirtualProducts : Boolean body: if self.redenedIncludeVirtualProducts -> notEmpty() then self.redenedIncludeVirtualProducts else self.tableRate.genericIncludeVirtualProducts endif [14] FreeShippingInWebsite :: minimumOrderAmount is the redenedMinimumOrderAmount. If theres no redenition at the website level, it is the generic value. Context FreeShippingInWebsite :: minimumOrderAmount : Money body: if self.redenedMinimumOrderAmount -> notEmpty() then self.redenedMinimumOrderAmount If

32

else self.freeShipping.genericMinimumOrderAmount endif [15] ExternalShippingMethodInWebsite :: gatewayURL is the redenedGatewayURL. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: gatewayURL : URL body: if self.redenedGatewayURL -> notEmpty() then self.redenedGatewayURL else self.externalShippingMethod.genericGatewayURL endif [16] ExternalShippingMethodInWebsite :: maxPackageWeight is the redenedMaxPackageWeight. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: maxPackageWeight : Weight body: if self.redenedMaxPackageWeight -> notEmpty() then self.redenedMaxPackageWeight else self.externalShippingMethod.genericMaxPackageWeight endif [17] ExternalShippingMethodInWebsite :: handlingApplied is the redenedHandlingApplied. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: handlingApplied : HandlingMethod body: if self.redenedHandlingApplied -> notEmpty() then self.redenedHandlingApplied else self.externalShippingMethod.genericHandlingApplied endif [18] ExternalShippingMethodInWebsite :: allowedSpecicMethods is the redenedAllowedSpecicMethods. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: allowedSpecicMethods : Set(ExternalSpecicShippingMethod) body: if self.redenedAllowedSpecicMethods -> notEmpty() then self.redenedAllowedSpecicMethods else self.externalShippingMethod.genericAllowedSpecicMethods endif [19] ExternalShippingMethodInWebsite :: freeSpecicMethod is the redenedFreeSpecicMethod. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: freeSpecicMethod : ExternalSpecicShippingMethod body: if self.redenedFreeSpecicMethod -> notEmpty() then self.redenedFreeSpecicMethod else self.externalShippingMethod.genericFreeSpecicMethod endif [20] ExternalShippingMethodInWebsite :: minimumAmountForFreeShipping is the redenedMinimumAmountForFreeShipping. If theres no redenition at the website level, it is the generic value. Context ExternalShippingMethodInWebsite :: minimumAmountForFreeShipping : Money body: if self.redenedMinimumAmountForFreeShipping -> notEmpty() then self.redenedMinimumAmountForFreeShipping

33

else self.externalShippingMethod.genericMinimumAmountForFreeShipping endif [21] UPSInWebsite :: container is the redenedContainer. If theres no redenition at the website level, it is the generic value. Context UPSInWebsite :: container : USPSContainer body: if self.redenedContainer -> notEmpty() then self.redenedContainer else self.uPS.genericContainer endif [22] UPSInWebsite :: destinationType is the redenedDestinationType. If theres no redenition at the website level, it is the generic value. Context UPSInWebsite :: destinationType : Destination body: if self.redenedDestinationType -> notEmpty() then self.redenedDestinationType else self.uPS.genericDestinationType endif [23] UPSInWebsite :: pickup is the redenedPickup. If theres no redenition at the website level, it is the generic value. Context UPSInWebsite :: pickup : UPSPickupMethod body: if self.redenedPickup -> notEmpty() then self.redenedPickup else self.uPS.genericPickup endif [24] USPSInWebsite :: userID is the redenedUserID. If theres no redenition at the website level, it is the generic value. Context USPSInWebsite :: userID : String body: if self.redenedUserID -> notEmpty() then self.redenedUserID else self.uSPS.genericUserID endif [25] USPSInWebsite :: container is the redenedContainer. If theres no redenition at the website level, it is the generic value. Context USPSInWebsite :: container : USPSContainer body: if self.redenedContainer -> notEmpty() then self.redenedContainer else self.uSPS.genericContainer endif [26] USPSInWebsite :: size is the redenedSize. If theres no redenition at the website level, it is the generic value. Context USPSInWebsite :: size : USPSSize body: if self.redenedSize -> notEmpty() then self.redenedSize else self.uSPS.genericSize

34

endif [27] FedExInWebsite :: userID is the redenedUserID. If theres no redenition at the website level, it is the generic value. Context FedExInWebsite :: userID : String body: if self.redenedUserID -> notEmpty() then self.redenedUserID else self.fedEx.genericUserID endif [28] FedExInWebsite :: container is the redenedContainer. If theres no redenition at the website level, it is the generic value. Context FedExInWebsite :: container : FedExContainer body: if self.redenedContainer -> notEmpty() then self.redenedContainer else self.fedEx.genericContainer endif [29] FedExInWebsite :: destinationType is the redenedDestinationType. If theres no redenition at the website level, it is the generic value. Context FedExInWebsite :: destinationType : Destination body: if self.redenedDestinationType -> notEmpty() then self.redenedDestinationType else self.fedEx.genericDestinationType endif [30] FedExInWebsite :: pickup is the redenedPickup. If theres no redenition at the website level, it is the generic value. Context FedExInWebsite :: pickup : FedExPickupMethod body: if self.redenedPickup -> notEmpty() then self.redenedPickup else self.fedEx.genericPickup endif [31] DHLInWebsite :: userID is the redenedUserID. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: userID : String body: if self.redenedUserID -> notEmpty() then self.redenedUserID else self.dHL.genericUserID endif [32] DHLInWebsite :: container is the redenedContainer. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: container : DHLContainer body: if self.redenedContainer -> notEmpty() then self.redenedContainer else self.dHL.genericContainer endif

35

[33] DHLInWebsite :: password is the redenedPassword. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: password : String body: if self.redenedPassword -> notEmpty() then self.redenedPassword else self.dHL.genericPassword endif [34] DHLInWebsite :: accountNumber is the redenedAccountNumber. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: accountNumber : String body: if self.redenedAccountNumber -> notEmpty() then self.redenedAccountNumber else self.dHL.genericAccountNumber endif [35] DHLInWebsite :: shippingKey is the redenedShippingKey. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: shippingKey : String body: if self.redenedShippingKey -> notEmpty() then self.redenedShippingKey else self.dHL.genericShippingKey endif [36] DHLInWebsite :: internationalShippingKey is the redenedInternationalShippingKey. theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: internationalShippingKey : String body: if self.redenedInternationalShippingKey -> notEmpty() then self.redenedInternationalShippingKey else self.dHL.genericInternationalShippingKey endif [37] DHLInWebsite :: packageDescription is the redenedPackageDescription. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: packageDescription : String body: if self.redenedPackageDescription -> notEmpty() then self.redenedPackageDescription else self.dHL.genericPackageDescription endif [38] DHLInWebsite :: isShipmentDurable is the redenedIsShipmentDurable. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: isShipmentDurable : Boolean body: if self.redenedIsShipmentDurable -> notEmpty() then self.redenedIsShipmentDurable else self.dHL.genericIsShipmentDurable endif If

36

[39] DHLInWebsite :: dutyPaymentType is the redenedDutyPaymentType. If theres no redenition at the website level, it is the generic value. Context DHLInWebsite :: dutyPaymentType : DHLDutyPaymentType body: if self.redenedDutyPaymentType -> notEmpty() then self.redenedDutyPaymentType else self.dHL.genericDutyPaymentType endif

Constraints
[1] There is only one shipping method for each shipping method subtype, so shipping methods are identied by its subtypes. Context ShippingMethod :: isIdentiedByItsSubtype() : Boolean body: FlatRate.allInstances() -> size() = 1 and TableRate.allInstances() -> size() = 1 and FreeShipping.allInstances() -> size() = 1 and UPS.allInstances() -> size() = 1 and USPS.allInstances() -> size() = 1 and FedEx.allInstances() -> size() = 1 and DHL.allInstances() -> size() = 1 [2] A shipping method in a store view is identied by its title and store view.

Context ShippingMethodInStoreView :: isIdentiedByItsTitleAndStoreView() : Boolean body: ShippingMethodInStoreView.allInstances() -> isUnique(Settitle,storeView) [3] Each shipping method should be specied in all existing store views in the system.

Context ShippingMethod :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() ) [4] Each shipping method should be specied in all existing websites in the system.

Context ShippingMethod :: isSpeciedInAllWebsites() : Boolean body: self.website -> includesAll( Website.allInstances() ) [5] Each internal shipping method should be specied in all existing websites in the system.

Context InternalShippingMethod :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfInternalShippingMethod -> includesAll( Website.allInstances() ) [6] Each external shipping method should be specied in all existing websites in the system.

Context ExternalShippingMethod :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfExternalShippingMethod -> includesAll( Website.allInstances() ) [7] The ate rate method should be specied in all existing websites in the system.

Context FlatRate :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfFlatRate -> includesAll( Website.allInstances() ) [8] The table rate method should be specied in all existing websites in the system.

37

Context TableRate :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfTableRate -> includesAll( Website.allInstances() ) [9] The free shipping method should be specied in all existing websites in the system.

Context FreeShipping :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfFreeShipping -> includesAll( Website.allInstances() ) [10] The UPS method should be specied in all existing websites in the system.

Context UPS :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfUPS -> includesAll( Website.allInstances() ) [11] The USPS method should be specied in all existing websites in the system.

Context USPS :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfUSPS -> includesAll( Website.allInstances() ) [12] The FedEx method should be specied in all existing websites in the system.

Context FedEx :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfFedEx -> includesAll( Website.allInstances() ) [13] The DHL method should be specied in all existing websites in the system.

Context DHL :: isSpeciedInAllWebsites() : Boolean body: self.websiteOfDHL -> includesAll( Website.allInstances() ) [14] There is at least one enabled shipping method

Context Website :: hasOneShippingMethodEnabledAtLeast() : Boolean body: self.shippingMethodInWebsite -> select (pm | pm.status=Status::Enabled) -> size() >= 1 [15] The free shipping method does not have any handling fee dened.

Context FreeShipping :: hasNoHandlingFee() : Boolean body: self.handlingFee.isUndened() and self.handlingCalculatingMethod.isUndened()

Description
The Magento store administrator can customize the shipping methods that are available at checkout time. During the checkout process, the chosen method is used to calculate the nal shipping and packaging costs for the order. Depending on the selected method, the price can be affected by how many products have been ordered, how much they weigh or other criteria. We present here the Shipping Methods allowed by Magento: Flat rate: a single price is used on all orders, regardless of how many items are bought, how much everything weighs, etc. Table rates: table rate charging sets the price for shipping based on the total weight, the total orders price or the number of the products ordered. The weight or price is looked up in a table to nd the matching range, and then that price is applied. Free shipping: no cost is added when using this method. The store administrator can establish a minimum order amount for this method to be applicable. UPS: interacts with the external United Parcel Service website. 38

USPS: interacts with the external United States Postal Service website. FedEx: interacts with the external FedEx Corporation website. DHL: interacts with the external Deutsche Post DHL website. For all shipping methods, some properties should be dened: status: denes if the method is available or not for customers. title: the name the users will see for this method. allowedCountry: only the Orders shipped to this countries will be able tu use the current shipping method. showIfNotApplicable: determinates if the method will be displayed if the customer does not meet the country requirements. errorMessage: the message that will be displayed when the customer does not meet the country requirements, if the showIfNotApplicable property is set to true. handlingFee: an additional shipping cost that will be added. handlingCalculatingMethod: the way the upper cost will be calculated, adding the whole quantity or as a percent. The rst tree shipping methods described above are internally dened by magento. For each one, we should dene the method name that will be used to show to the customers. The last four methods interact with external shipping services websites to calculate the shipping cost. For that methods, we should dene the following properties: gatewayURL: the url to connect with the service. maximumPackageWeight: the maximum weight allowed for an single shipment. handlingApplied: determines if the handling fee will be applied for each shipment or only once per order. allowedSpecicMethods: set of specic shipping methods that each external shipping service provides. freeSpecicMethod: denes one specic method of this service that the store decides to offer for free. minimumAmountForFreeShipping: if this minimum amount is not reached by the order total price, the free specic method will be offered with its normal price. userID: the id account provided by the external shipping service to identicate the store. container: the type of container that will be tipically used to package the sold items. destinationType: the destination to which the store will typically deliver its orders. pickupMethod: the method by which the store will deliver its packages to the shipping service. The DHL Service has several other properties that should be dened. They are internal congurations to identicate ourselves at the DHL system, and fall out of the Magento conceptual model.

39

2.4.6
I

Payment Methods

Overview
The system can operate with different payment methods.

Schema Diagram

40

41

Derivation Rules
[1] PaymentMethodInWebsite :: allowedCountry the redenedAllowedCountry. If theres no redenition at the website level, it is the generic value. Context PaymentMethodInWebsite :: allowedCountry : Set(Country) body: if self.redenedAllowedCountry -> notEmpty() then self.redenedAllowedCountry else self.shippingMethod.genericAllowedCountry

42

endif [2] PaymentMethodInWebsite :: status is the redenedStatus. If theres no redenition at the website level, it is the generic value. Context PaymentMethodInWebsite :: status : Status body: if self.redenedStatus -> notEmpty() then self.redenedStatus else self.paymentMethod.genericStatus endif [3] PaymentMethodInWebsite :: newOrderStatus is the redenedNewOrderStatus. If theres no redenition at the website level, it is the generic value. Context PaymentMethodInWebsite :: newOrderStatus : OrderStatus body: if self.redenedNewOrderStatus -> notEmpty() then self.redenedNewOrderStatus else self.paymentMethod.genericNewOrderStatus endif [4] PaymentMethodInWebsite :: minimumAllowed is the redenedMinimumAllowed. If theres no redenition at the website level, it is the generic value. Context PaymentMethodInWebsite :: minimumAllowed : Money body: if self.redenedMinimumAllowed -> notEmpty() then self.redenedMinimumAllowed else self.paymentMethod.genericMinimumAllowed endif [5] PaymentMethodInWebsite :: maximumAllowed is the redenedMaximumAllowed. If theres no redenition at the website level, it is the generic value. Context PaymentMethodInWebsite :: maximumAllowed : Money body: if self.redenedMaximumAllowed -> notEmpty() then self.redenedMaximumAllowed else self.paymentMethod.genericMaximumAllowed endif [6] PaymentMethodInStoreView :: title is the redenedTitle. If theres no redenition at that level, it is the nearest upper redened value. Context PaymentMethodInStoreView :: title : String body: if self.redenedTitle -> notEmpty() then self.redenedTitle elseif self.paymentMethod.paymentMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedTitle -> notEmpty() then self.paymentMethod.paymentMethodInWebsite -> select ( smiw | smiw.website.store.storeView -> includes ( self.storeView ) ).redenedTitle else self.paymentMethod.genericTitle endifendif [7] CreditCardMethodInWebsite :: allowedCard is the redenedAllowedCard. If theres no redenition at the website level, it is the generic value. Context CreditCardMethodInWebsite :: allowedCard : Set(CreditCardType) body: if self.redenedAllowedCard -> notEmpty() then

43

self.redenedAllowedCard else self.creditCardMethod.genericAllowedCard endif [8] CreditCardMethodInWebsite :: cardValidation is the redenedCardValidation. If theres no redenition at the website level, it is the generic value. Context CreditCardMethodInWebsite :: cardValidation : Boolean body: if self.redenedCardValidation -> notEmpty() then self.redenedCardValidation else self.creditCardMethod.genericCardValidation endif [9] CreditCardMethodInWebsite :: security3DCardValidation is the redenedSecurity3DCardValidation. If theres no redenition at the website level, it is the generic value. Context CreditCardMethodInWebsite :: security3DCardValidation : Boolean body: if self.redenedSecurity3DCardValidation -> notEmpty() then self.redenedSecurity3DCardValidation else self.creditCardMethod.genericSecurity3DCardValidation endif [10] CreditCardMethodInWebsite :: invoiceAutomatically is the redenedInvoiceAutomatically. If theres no redenition at the website level, it is the generic value. Context CreditCardMethodInWebsite :: invoiceAutomatically : Boolean body: if self.redenedInvoiceAutomatically -> notEmpty() then self.redenedInvoiceAutomatically else self.creditCardMethod.genericInvoiceAutomatically endif [11] CheckMoneyInWebsite :: payeeName is the redenedPayeeName. If theres no redenition at that level, it is the nearest upper redened value. Context CheckMoneyInWebsite :: payeeName : String body: if self.redenedPayeeName -> notEmpty() then self.redenedPayeeName else self.checkMoney.genericPayeeName endif [12] CheckMoneyInWebsite :: receiverName is the redenedReceiverName. If theres no redenition at that level, it is the nearest upper redened value. Context CheckMoneyInWebsite :: receiverName : String body: if self.redenedReceiverName -> notEmpty() then self.redenedReceiverName else self.checkMoney.genericReceiverName endif. [13] AuthorizeNetInWebsite :: username is the redenedUsername. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: username : String body: if self.redenedUsername -> notEmpty() then self.redenedUsername

44

else self.authorizeNet.genericUsername endif [14] AuthorizeNetInWebsite :: key is the redenedKey. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: key : String body: if self.redenedKey -> notEmpty() then self.redenedKey else self.authorizeNet.genericKey endif [15] AuthorizeNetInWebsite :: mode is the redenedMode. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: mode : TransactionMode body: if self.redenedMode -> notEmpty() then self.redenedMode else self.authorizeNet.genericMode endif [16] AuthorizeNetInWebsite :: notication is the redenedNotication. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: notication : Boolean body: if self.redenedNotication -> notEmpty() then self.redenedNotication else self.authorizeNet.genericNotication endif [17] AuthorizeNetInWebsite :: gatewayURL is the redenedGatewayURL. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: gatewayURL : URL body: if self.redenedGatewayURL -> notEmpty() then self.redenedGatewayURL else self.authorizeNet.genericGatewayURL endif [18] AuthorizeNetInWebsite :: merchantEmail is the redenedMerchantEmail. If theres no redefinition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: merchantEmail : Email body: if self.redenedMerchantEmail -> notEmpty() then self.redenedMerchantEmail else self.authorizeNet.genericMerchantEmail endif [19] AuthorizeNetInWebsite :: debugStatus is the redenedDebugStatus. If theres no redenition at the website level, it is the generic value. Context AuthorizeNetInWebsite :: debugStatus : Status body: if self.redenedDebugStatus -> notEmpty() then self.redenedDebugStatus else

45

self.authorizeNet.genericDebugStatus endif [20] PayFlowProInWebsite :: mode is the redenedMode. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: mode : TransactionMode body: if self.redenedMode -> notEmpty() then self.redenedMode else self.payFlowPro.genericMode endif [21] PayFlowProInWebsite :: method is the redenedMethod. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: method : TransactionMethod body: if self.redenedMethod -> notEmpty() then self.redenedMethod else self.payFlowPro.genericMethod endif [22] PayFlowProInWebsite :: verboseInformation is the redenedVerboseInformation. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: verboseInformation : Boolean body: if self.redenedVerboseInformation -> notEmpty() then self.redenedVerboseInformation else self.payFlowPro.genericVerboseInformation endif [23] PayFlowProInWebsite :: debugStatus is the redenedDebugStatus. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: debugStatus : Status body: if self.redenedDebugStatus -> notEmpty() then self.redenedDebugStatus else self.payFlowPro.genericDebugStatus endif [24] PayFlowProInWebsite :: accountInfo is the redenedAccountInfo. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: accountInfo : PayFlowProAccount body: if self.redenedAccountInfo -> notEmpty() then self.redenedAccountInfo else self.payFlowPro.genericAccountInfo endif [25] PayFlowProInWebsite :: proxy is the redenedProxy. If theres no redenition at the website level, it is the generic value. Context PayFlowProInWebsite :: proxy : Proxy body: if self.redenedProxy -> notEmpty() then self.redenedProxy else self.payFlowPro.genericProxy

46

endif [26] PayPalMethodInWebsite :: mode is the redenedMode. If theres no redenition at the website level, it is the generic value. Context PayPalMethodInWebsite :: mode : TransactionMode body: if self.redenedMode -> notEmpty() then self.redenedMode else self.payPalMethod.genericMode endif [27] PayPalMethodInWebsite :: accountInfo is the redenedAccountInfo. If theres no redenition at the website level, it is the generic value. Context PayPalMethodInWebsite :: accountInfo : PayPalAccount body: if self.redenedAccountInfo -> notEmpty() then self.redenedAccountInfo else self.payPalMethod.genericAccountInfo endif [28] PayPalMethodInWebsite :: transferCartLineItems is the redenedTransferCartLineItems. If theres no redenition at the website level, it is the generic value. Context PayPalMethodInWebsite :: transferCartLineItems : Boolean body: if self.redenedTransferCartLineItems -> notEmpty() then self.redenedTransferCartLineItems else self.payPalMethod.genericTransferCartLineItems endif [29] PayPalExpressCheckoutInWebsite :: guestCheckoutStatus is the redenedGuestCheckoutStatus. If theres no redenition at the website level, it is the generic value. Context PayPalExpressCheckoutInWebsite :: guestCheckoutStatus : Status body: if self.redenedGuestCheckoutStatus -> notEmpty() then self.redenedGuestCheckoutStatus else self.payPalExpressCheckout.genericGuestCheckoutStatus endif [30] GoogleCheckoutInWebsite :: mode is the redenedMode. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: mode : TransactionMode body: if self.redenedMode -> notEmpty() then self.redenedMode else self.googleCheckout.genericMode endif [31] GoogleCheckoutInWebsite :: debugStatus is the redenedDebugStatus. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: debugStatus : Status body: if self.redenedDebugStatus -> notEmpty() then self.redenedDebugStatus else self.googleCheckout.genericDebugStatus endif

47

[32] GoogleCheckoutInWebsite :: accountInfo is the redenedAccountInfo. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: accountInfo : GoogleCheckoutAccount body: if self.redenedAccountInfo -> notEmpty() then self.redenedAccountInfo else self.googleCheckout.genericAccountInfo endif [33] GoogleCheckoutInWebsite :: continueShoppingURL is the redenedContinueShoppingURL. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: continueShoppingURL : URL body: if self.redenedContinueShoppingURL -> notEmpty() then self.redenedContinueShoppingURL else self.googleCheckout.genericContinueShoppingURL endif [34] GoogleCheckoutInWebsite :: requireSecureCallback is the redenedRequireSecureCallback. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: requireSecureCallback : Boolean body: if self.redenedRequireSecureCallback -> notEmpty() then self.redenedRequireSecureCallback else self.googleCheckout.genericRequireSecureCallback endif [35] GoogleCheckoutInWebsite :: disableDefaultTaxTables is the redenedDisableDefaultTaxTables. If theres no redenition at the website level, it is the generic value. Context GoogleCheckoutInWebsite :: disableDefaultTaxTables : Boolean body: if self.redenedDisableDefaultTaxTables -> notEmpty() then self.redenedDisableDefaultTaxTables else self.googleCheckout.genericDisableDefaultTaxTables endif

Constraints
[1] There is only one payment method for each payment method subtype, so payment methods are identied by its subtypes. Context PaymentMethod :: isIdentiedByItsSubtype() : Boolean body: CreditCard.allInstances() -> size() = 1 and ZeroSubtotalCheckout.allInstances() -> size() = 1 and CheckMoney.allInstances() -> size() = 1 and PurchaseOrder.allInstances() -> size() = 1 and AuthorizeNet.allInstances() -> size() = 1 and PayFlowPro.allInstances() -> size() = 1 and PayPalExpressCheckout.allInstances() -> size() = 1 and PayPalDirectPayment.allInstances() -> size() = 1 and PayPalStandard.allInstances() -> size() = 1 and GoogleCheckout.allInstances() -> size() = 1 [2] For a given store view, each payment method has a unique title.

48

Context StoreView :: doesNotHaveTwoPaymentMethodsWithTheSameRedenedName() : Boolean body: self.paymentMethodInStoreView -> isUnique (title) [3] Each payment method should be specied in all existing store views in the system.

Context PaymentMethod :: isSpeciedInAllStoreViews() : Boolean body: PaymentMethod.storeView -> includesAll( StoreView.allInstances() ) [4] Each payment method should be specied in all existing websites in the system.

Context PaymentMethod :: isSpeciedInAllWebsites() : Boolean body: PaymentMethod.website -> includesAll( Website.allInstances() ) [5] Each credit card method should be specied in all existing websites in the system.

Context CreditCardMethod :: isSpeciedInAllWebsites() : Boolean body: CreditCardMethod.website -> includesAll( Website.allInstances() ) [6] The simple credit card method should be specied in all existing websites in the system.

Context CreditCard :: isSpeciedInAllWebsites() : Boolean body: CreditCard.website -> includesAll( Website.allInstances() ) [7] The zero subtotal checkout method should be specied in all existing websites in the system.

Context ZeroSubtotalCheckout :: isSpeciedInAllWebsites() : Boolean body: ZeroSubtotalCheckout.website -> includesAll( Website.allInstances() ) [8] The check money method should be specied in all existing websites in the system.

Context CheckMoney :: isSpeciedInAllWebsites() : Boolean body: CheckMoney.website -> includesAll( Website.allInstances() ) [9] The purchase order method should be specied in all existing websites in the system.

Context PurchaseOrder :: isSpeciedInAllWebsites() : Boolean body: PurchaseOrder.website -> includesAll( Website.allInstances() ) [10] The Authorize.Net method should be specied in all existing websites in the system.

Context AuthorizeNet :: isSpeciedInAllWebsites() : Boolean body: AuthorizeNet.website -> includesAll( Website.allInstances() ) [11] The Pay Flow Pro method should be specied in all existing websites in the system.

Context PayFlowPro :: isSpeciedInAllWebsites() : Boolean body: PayFlowPro.website -> includesAll( Website.allInstances() ) [12] Each Pay Pal method should be specied in all existing websites in the system.

Context PayPalMethod :: isSpeciedInAllWebsites() : Boolean body: PayPalMethod.website -> includesAll( Website.allInstances() ) [13] The Pay Pal Express Checkout method should be specied in all existing websites in the system.

49

Context PayPalExpressCheckout :: isSpeciedInAllWebsites() : Boolean body: PayPalExpressCheckout.website -> includesAll( Website.allInstances() ) [14] The Pay Pal Direct Payment method should be specied in all existing websites in the system.

Context PayPalDirectPayment :: isSpeciedInAllWebsites() : Boolean body: PayPalDirectPayment.website -> includesAll( Website.allInstances() ) [15] The Pay Pal Standard method should be specied in all existing websites in the system.

Context PayPalStandard :: isSpeciedInAllWebsites() : Boolean body: PayPalStandard.website -> includesAll( Website.allInstances() ) [16] The Google Checkout method should specied in all existing websites in the system.

Context GoogleCheckout :: isSpeciedInAllWebsites() : Boolean body: GoogleCheckout.website -> includesAll( Website.allInstances() ) [17] There is at least one enabled payment method

Context PaymentMethod :: hasOneInstanceEnabledAtLeast() : Boolean body: PaymentMethod.allInstances() -> select (pm | pm.status=Status::Enabled) -> size() >= 1 [18] The PayPal and Google Checkout methods can not dene a minimum and maximum order amount allowed Context PaymentMethodInWebsite :: denesMinAndMaxAllowedOnlyWhenNeeded() : Boolean body: ( self.oclIsTypeOf( PayPalMethodInWebsite ) or self.oclIsTypeOf( GoogleCheckoutInWebsite ) ) implies ( self.minimumAllowed.isUndened() and self.maximumAllowed.isUndened() ) [19] The zero subtotal chekout method denes the minimum and maximum order amount allowed as zero. Context ZeroSubtotalCheckoutInWebsite :: isOnlyAvailableWithFreeOrders() : Boolean body: self.minimumAllowed = 0 and self.maximumAllowed = 0 [20] Google checkout can only be applied at the United Kingdom and the United States.

Context GoogleCheckout :: isOnlyAvailableInUKAndUS() : Boolean body: self.allowedCountry -> forAll ( c | c.name = United Kingdom or c.name = United States)

Description
The system allows customers to pay through different payment methods, which can be enabled or disabled and congured by the store administrator. Some of the payment methods, like Authorize.net, PayFlow, PayPal or GoogleCheckout, involve an external company. The Credit Card, ZeroSubtotalCheckout and PurchaseOrder methods simply store information for off-line processing. There is also a method available for money order and check payments which do not involve an external merchant. For all shipping methods, some properties should be dened: status: denes if the method is available or not for customers. 50

title: the name the users will see for this method. allowedCountry: only the Orders shipped to this countries will be able tu use the current shipping method. newOrderStatus: the Order Status of all new Orders created using this payment method. For methods using a credit card, we should dene which card types are allowed, and if a security validation is needed. Some payment methods have specic or partially shared properties rellevant to the system behaviour: minimumTotalAllowed: if the value is dened, the payment method will only be listed for those orders whose total is above the minimum. maximumTotalAllowed: if the value is dened, the payment method will only be listed for those orders whose total is below the maximum. invoiceAutomatically: if true, the system will automatically invoice the whole order. All the payment methods have other specic information about all the data needed to process the payment. It has no effect on the Magento system.

51

2.4.7
I

Taxes

Overview
In order to supply a exible use of taxes, product prices are stored tax free. The nal price is calculated taking into account the customer tax class, the adress the products will be shipped and the products tax class.

Schema Diagram

Derivation Rules
[1] TaxRateInStoreView :: name is the redenedName. If theres no redenition at the store view level, it is the generic value. Context TaxRateInStoreView :: name : String body:

52

if self.redenedName -> notEmpty() then self.redenedName else self.taxRate.genericName endif [2] TaxRate :: applicableAdress are the municipalities where the tax rate can be applied.

Context TaxRate :: applicableAdress : Set(Adress) body: if self.explicitPostalArea -> notEmpty() then self.explicitPostalArea.address -> asSet() else if self.explicitZone -> notEmpty() then self.explicitZone.adress -> union(self.explicitZone.municipality.address) -> asSet() else self.explicitCountry.address -> union(self.explicitCountry.municipality.address) -> asSet() endif endif

I
[1]

Constraints
Tax rates are identied by its generic name.

Context TaxRate :: isIdentiedByGenericName() : Boolean body: TaxRate.allInstances() -> isUnique(genericName) [2] Tax rules are identied by its name.

Context TaxRule :: isIdentiedByName() : Boolean body: TaxRule.allInstances() -> isUnique(name) [3] Customer Tax Classes are identied by its name.

Context CustomerTaxClass :: isIdentiedByName() : Boolean body: CustomerTaxClass.allInstances() -> isUnique(name) [4] Product Tax Classes are identied by its name.

Context ProductTaxClass :: isIdentiedByName() : Boolean body: ProductTaxClass.allInstances() -> isUnique(name) [5] .

Context TaxRate :: hasZoneAndMunicipalitiesFromTheExplicitCountry() : Boolean body: self.explicitCountry.zone -> includes(self.explicitZone) and self.explicitCountry.zone.municipality.postalArea -> includesAll(self.explicitPostalArea) [6] If the a taxRate is associated to a Country that has zones and a Zone, the zone should be from this country. Context TaxRate :: haveACorrectZoneIfNeeded() : Boolean body: ( self.explicitCountry.zone -> notEmpty() and self.explicitZone -> notEmpty() )implies self.explicitCountry = self.explicitZone.country [7] A tax rate should be located in either a country, a zone or a municipality, or some of them.

Context TaxRate :: isLocated() : Boolean body: self.explicitCountry -> notEmpty() or self.explicitZone -> notEmpty() or self.explicitPostalArea -> notEmpty()

53

Description
Magento allows Administrators to set up different types of taxes and relate them to the zones where they can be applied. Tax Classes group products or customers that will be treated in the same way when deciding which taxes should be applied. Customer Tax Classes group Customers throught Customer Groups, and Product Tax Classes group Products. A Tax Rate dene the rate that can be applied as a tax. It also denes where the tax can be applied, by dening a Country, a Zone and/or several Postal Areas. The tax will be applied to Orders which rateApplicationAdress is one of the applicableAdress. Those are calculated when the order is placed, taking the adresses that belong to one of the explicit postal areas dened. If no one is dened, the tax will be able to be applicated to all Orders belonging to the dened Zone, or the whole Country if no Zone is dened. A Tax Rate can be displayed with a different name in each StoreView. This name will be dened as the title attribute of the TaxTitle entity type. If no title is dened for one StoreView, the tax rate identier will be used instead. Theres no integrity constraint related to tax titles identication, as a TaxTitle can be identied by its StoreView and TaxRate, the identicable entities that participate in the relationship type that TaxTitle represents. Finally, a Tax Rule denes when a tax Rate will be able to be applied, but now depending on the Customer and Product Tax Classes. A tax rule is associated to three non-empty sets of Customer Tax Classes, Product Tax Classes and Tax Rates. When one rule is applied to an Order Line, it will check if the product ordered and the orders customer are included in one of its respective tax classes. If true, the tax rates associated to this rule will be able to be applicated, depending on the municipality where the Order is shipped. Moreover, Tax Rules are ordered by priorities, and these priorities can be repeated between rules. When deciding which taxes we should apply to an Order Line, only the rules with the higher priority number will be taken into account. If there are more than one, all of them will be applied.

54

2.5 Customers
2.5.1
I

Customers

Overview
Magento saves information about system users, which can be either Costumers or Administrators. Magento groupes customers in CostumerGroups.

Schema Diagram

55

Derivation Rules
[1] Website :: visibleCustomer are the costumers that can place orders, review and tag products, use shopping cards, etc. in this website. Depending on the "shareAccountScope", costumer accounts are visible throught all the websites or just in the website where they where created. Context Website :: visibleCustomer : Set(Customer) body: if CustomerConguration.shareAccountScope = Scope::Global then Customer.allInstances() else self.customer endif

Constraints
[1] Each customer from the same Website has a different eMail, but if the account visibility is set to Website, it can be repeated through different Websites. Context Customer :: isIdentiedByItsEmailAndTheWebsitesWhereIsVisible() : Boolean body: Customer.allInstances() -> isUnique(SeteMail,websiteWhereIsVisible) [2] Each administrator is identied by its user name.

Context Administrator :: isIdentiedByItsUserName() : Boolean body: Administrator.allInstances() -> isUnique(userName) [3] Each administrator is identied by its eMail.

Context Administrator :: isIdentiedByItsEmail() : Boolean body: Administrator.allInstances() -> isUnique(eMail) [4] Each role is identied by its name.

Context Role :: isIdentiedByItsName() : Boolean body: Role.allInstances() -> isUnique(name) [5] The customer is created in a store view that belongs to the website where it was created.

Context Customer :: isCreatedInACorrectStoreView() : Boolean body: self.websiteWhereIsAssociated.store.storeView -> includes (self.storeViewWhereIsCreated) [6] At least an instance of customer group called NotLoggedIn exists in the system.

Context CustomerGroup :: hasTheNotLoggedInInstance() : Boolean body: CustomerGroup.allInstances() -> exists(g|g.name = NotLoggedIn) [7] At least an instance of customer group called General exists in the system.

Context CustomerGroup :: hasTheGeneralInstance() : Boolean body: CustomerGroup.allInstances() -> exists(g|g.name = General)

Description
Magento has the following information about Users, even if they are Costumers or Administrators: 56

rstName: The rst name of the user. lastName: The last name of the user. password: The password used by a user to be identied when logging in the system. eMail: The users email. There are neither two Costumers nor two Administrators with the same email, but we can have a Customer and an Administrator with the same email. This email is used for identifying costumers when they log in. Just for Administrators, Magento has the following information: userName: An small nickname the administrator will use to identicate himself when logging in the system. status: Indicates whether the administrator is allowed to access to the admin panel and use it. By this way, an administrator can be disabled without deleting his information. Each administrator should be associated to a Role. The role will determine the admin functionalities he will be able to use. For each Costumer, the system saves (or can optionally save) other personal and system information: namePrex middleName nameSufx dateOfBirth taxVatNumber: an identier used for taxation purposes. createdAt: the time the costumer was created. lastLoggedIn: the last time the customer logged in the system. accountConrmed: indicates whether the system has checked that the customer has entered an existing e-mail. Costumers are associated to a website. If the user has been created from the front-end, the store view where the registration process have been done is saved. Additonaly, Customers can have many adresses associated. When purchasing a product, the user will choose which of his adresses are used as delivery and billing adresses. The user can previously dene what adresses would be used by default, those are the defaultBilling and defaultDelivery addresses. Address rst, middle and last name, name prex and name sufx may not have the same values in the customer where the address is associated. A customer can specify the store to ship or bill its products to an address where his name doesnt appear, for example as a gift to a friend. Magento makes you associate each customer to a CustomerGroup. The aim of this Customer group is to apply some Magentos features to groups of costumers all at once. A name is dened for each group and identies it.

57

2.5.2
I

Sessions

Overview
Each active access to the system is a session. Sessions can be anonymous or can be associated to a registered customer.

Schema Diagram

Derivation Rules
[1] Session :: customerGroup for customer sessions, the customer group of the corresponding customer. For anonymous session, the group named NotLoggedIn. Context Session :: customerGroup : CustomerGroup body: if self.oclIsTypeOf(CustomerSession) then self.oclAsType(CustomerSession).customer.customerGroup else CustomerGroup.allInstances() -> any ( c | c.name = NotLoggedIn ) endif [2] Customer :: online indicates whether the costumer is currently using the system. Thats, the customer has an active session Context Customer :: online : Boolean body: self.customerSession -> notEmpty()

58

Constraints
[1] Each anonymous session is identied by its IP address.

Context AnonymousSession :: isIdentiedByItsIPAddress() : Boolean body: AnonymousSession.allInstances() -> isUnique(ipAddress) [2] Each customer session is identied by its associated customer.

Context CustomerSession :: isIdentiedByItsCostumer() : Boolean body: CustomerSession.allInstances() -> isUnique(customer) [3] the current currency should be one of the allowed currencies the session is currently using.

Context Session :: displaysAnAllowedCurrency() : Boolean body: self.storeView.currencyCongurationInStoreView.allowedCurrency -> includes(self.currentCurrency) [4] the sessions store view should be enabled.

Context Session :: isPlacedInAnEnabledStoreView() : Boolean body: self.storeView.status = Status::Enabled

Description
A session maintains information about everyone which is now using the system. There is one CustomerSession for each registered customer logged in the system. There is one AnonymousSession for each person who is currently in the system without being logged in. We will refer to them as Guests. Moreover, there are not Sessions representing an Administrator using now the system. A session saves the following information. ipAddress: The IP adress from which a costumer is accessing the site. sessionStartTime: The time this session has begun. lastActivityAt: The time the most recent activity in the site has been done. currentCurrency: the currency selected by the costumer to see the prices and monetary amounts in the site. storeView: the storeView the customer is currently using.

59

2.6 Store Administration


2.6.1
I

Products

Overview
The system knows the information about the products of the online store.

Schema Diagram

60

61

Derivation Rules
[1] ProductInStoreView :: name is the redenedName at the current base scope level (the base scope level is dened by the nameScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: name : String body: if self.redenedName -> notEmpty() and ProductPropertiesScopeConguration.nameScope= Scope::StoreView then self.redenedName

62

else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedName -> notEmpty() and ProductPropertiesScopeConguration.nameScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedName else self.product.genericName endif [2] ProductInWebsite :: netPrice is the redenedNetPrice. If theres no redenition at that level, it is the nearest upper redened value. Context ProductInWebsite :: netPrice : Money body: if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedNetPrice -> notEmpty() then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedNetPrice else self.product.genericNetPrice endif [3] ProductInStoreView :: weight is the redenedWeight at the current base scope level (the base scope level is dened by the weightScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: weight : Decimal body: if self.redenedWeight -> notEmpty() and ProductPropertiesScopeConguration.weightScope= Scope::StoreView then self.redenedWeight else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedWeight -> notEmpty() and ProductPropertiesScopeConguration.weightScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedWeight else self.product.genericWeight endif [4] ProductInStoreView :: status is the redenedStatus at the current base scope level (the base scope level is dened by the statusScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: status : Status body: if self.redenedStatus -> notEmpty() and ProductPropertiesScopeConguration.statusScope= Scope::StoreView then self.redenedStatus else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedStatus -> notEmpty() and ProductPropertiesScopeConguration.statusScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedStatus else self.product.genericStatus endif [5] ProductInStoreView :: isNewFrom is the redenedIsNewFrom at the current base scope level (the base scope level is dened by the isNewFromScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: isNewFrom : Date body: if self.redenedIsNewFrom -> notEmpty() and ProductPropertiesScopeConguration.isNewFromScope= Scope::StoreView then self.redenedIsNewFrom

63

else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsNewFrom -> notEmpty() and ProductPropertiesScopeConguration.isNewFromScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsNewFrom else self.product.genericIsNewFrom endif [6] ProductInStoreView :: isNewUntil is the redenedIsNewUntil at the current base scope level (the base scope level is dened by the isNewUntilScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: isNewUntil : Date body: if self.redenedIsNewUntil -> notEmpty() and ProductPropertiesScopeConguration.isNewUntilScope= Scope::StoreView then self.redenedIsNewUntil else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsNewUntil -> notEmpty() and ProductPropertiesScopeConguration.isNewUntilScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsNewUntil else self.product.genericIsNewUntil endif [7] ProductInWebsite :: specialNetPrice is the redenedSpecialNetPrice. If theres no redenition at that level, it is the nearest upper redened value. Context ProductInWebsite :: specialNetPrice : Money body: if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPrice -> notEmpty() then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPrice else self.product.genericSpecialNetPrice endif [8] ProductInStoreView :: specialNetPriceFrom is the redenedSpecialNetPriceFrom at the current base scope level (the base scope level is dened by the specialNetPriceFromScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: specialNetPriceFrom : Date body: if self.redenedSpecialNetPriceFrom -> notEmpty() and ProductPropertiesScopeConguration.specialNetPriceFromScope= Scope::StoreView then self.redenedSpecialNetPriceFrom else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPriceFrom -> notEmpty() and ProductPropertiesScopeConguration.specialNetPriceFromScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPriceFrom else self.product.genericSpecialNetPriceFrom endif [9] ProductInStoreView :: specialNetPriceUntil is the redenedSpecialNetPriceUntil at the current base scope level (the base scope level is dened by the specialNetPriceUntilScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: specialNetPriceUntil : Date body:

64

if self.redenedSpecialNetPriceUntil -> notEmpty() and ProductPropertiesScopeConguration.specialNetPriceUntilScope= Scope::StoreView then self.redenedSpecialNetPriceUntil else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPriceUntil -> notEmpty() and ProductPropertiesScopeConguration.specialNetPriceUntilScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSpecialNetPriceUntil else self.product.genericSpecialNetPriceUntil endif [10] ProductInStoreView :: description is the redenedDescription at the current base scope level (the base scope level is dened by the descriptionScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: description : String body: if self.redenedDescription -> notEmpty() and ProductPropertiesScopeConguration.descriptionScope= Scope::StoreView then self.redenedDescription else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedDescription -> notEmpty() and ProductPropertiesScopeConguration.descriptionScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedDescription else self.product.genericDescription endif [11] ProductInStoreView :: shortDescription is the redenedShortDescription at the current base scope level (the base scope level is dened by the shortDescriptionScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: shortDescription : String body: if self.redenedShortDescription -> notEmpty() and ProductPropertiesScopeConguration.shortDescriptionScope= Scope::StoreView then self.redenedShortDescription else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedShortDescription -> notEmpty() and ProductPropertiesScopeConguration.shortDescriptionScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedShortDescription else self.product.genericShortDescription endif [12] ProductInStoreView :: metaDescription is the redenedMetaDescription at the current base scope level (the base scope level is dened by the metaDescriptionScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: metaDescription : String body: if self.redenedMetaDescription -> notEmpty() and ProductPropertiesScopeConguration.metaDescriptionScope= Scope::StoreView then self.redenedMetaDescription else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaDescription -> notEmpty() and ProductPropertiesScopeConguration.metaDescriptionScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaDescription else self.product.genericMetaDescription

65

endif [13] ProductInStoreView :: metaKeyword is the redenedMetaKeyword at the current base scope level (the base scope level is dened by the metaKeywordScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: metaKeyword : String body: if self.redenedMetaKeyword -> notEmpty() and ProductPropertiesScopeConguration.metaKeywordScope= Scope::StoreView then self.redenedMetaKeyword else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaKeyword -> notEmpty() and ProductPropertiesScopeConguration.metaKeywordScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaKeyword else self.product.genericMetaKeyword endif [14] ProductInStoreView :: metaTitle is the redenedMetaTitle at the current base scope level (the base scope level is dened by the metaTitleScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: metaTitle : String body: if self.redenedMetaTitle -> notEmpty() and ProductPropertiesScopeConguration.metaTitleScope= Scope::StoreView then self.redenedMetaTitle else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaTitle -> notEmpty() and ProductPropertiesScopeConguration.metaTitleScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedMetaTitle else self.product.genericMetaTitle endif [15] ProductInStoreView :: imageGalleryPath is the redenedImageGalleryPath at the current base scope level (the base scope level is dened by the imageGalleryPathScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: imageGalleryPath : String body: if self.redenedImageGalleryPath -> notEmpty() and ProductPropertiesScopeConguration.imageGalleryPathScope= Scope::StoreView then self.redenedImageGalleryPath else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedImageGalleryPath -> notEmpty() and ProductPropertiesScopeConguration.imageGalleryPathScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedImageGalleryPath else self.product.genericImageGalleryPath endif [16] ProductInStoreView :: baseImagePath is the redenedBaseImagePath at the current base scope level (the base scope level is dened by the baseImagePathScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: baseImagePath : String body: if self.redenedBaseImagePath -> notEmpty() and ProductPropertiesScopeConguration.baseImagePathScope= Scope::StoreView then

66

self.redenedBaseImagePath else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedBaseImagePath -> notEmpty() and ProductPropertiesScopeConguration.baseImagePathScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedBaseImagePath else self.product.genericBaseImagePath endif [17] ProductInStoreView :: smallImagePath is the redenedSmallImagePath at the current base scope level (the base scope level is dened by the smallImagePathScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: smallImagePath : String body: if self.redenedSmallImagePath -> notEmpty() and ProductPropertiesScopeConguration.smallImagePathScope= Scope::StoreView then self.redenedSmallImagePath else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSmallImagePath -> notEmpty() and ProductPropertiesScopeConguration.smallImagePathScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedSmallImagePath else self.product.genericSmallImagePath endif [18] ProductInStoreView :: thumbnailPath is the redenedThumbnailPath at the current base scope level (the base scope level is dened by the thumbnailPathScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: thumbnailPath : String body: if self.redenedThumbnailPath -> notEmpty() and ProductPropertiesScopeConguration.thumbnailPathScope= Scope::StoreView then self.redenedThumbnailPath else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedThumbnailPath -> notEmpty() and ProductPropertiesScopeConguration.thumbnailPathScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedThumbnailPath else self.product.genericThumbnailPath endif [19] ProductInStoreView :: urlKey is the redenedUrlKey at the current base scope level (the base scope level is dened by the urlKeyScope property, in product properties scope conguration).If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: urlKey : String body: if self.redenedUrlKey -> notEmpty() and ProductPropertiesScopeConguration.urlKeyScope= Scope::StoreView then self.redenedUrlKey else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedUrlKey -> notEmpty() and ProductPropertiesScopeConguration.urlKeyScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedUrlKey else self.product.genericUrlKey endif

67

[20] ProductInStoreView :: isAvailableForGoogleCheckout is the redenedIsAvailableForGoogleCheckout at the current base scope level (the base scope level is dened by the isAvailableForGoogleCheckoutScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: isAvailableForGoogleCheckout : Boolean body: if self.redenedIsAvailableForGoogleCheckout -> notEmpty() and ProductPropertiesScopeConguration.isAvailableForGoogleCheckoutScope= Scope::StoreView then self.redenedIsAvailableForGoogleCheckout else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsAvailableForGoogleCheckout -> notEmpty() and ProductPropertiesScopeConguration.isAvailableForGoogleCheckoutScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedIsAvailableForGoogleCheckout else self.product.genericIsAvailableForGoogleCheckout endif [21] ProductInStoreView :: giftMessageAllowed is the redenedGiftMessageAllowed at the current base scope level (the base scope level is dened by the giftMessageAllowedScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: giftMessageAllowed : Boolean body: if self.redenedGiftMessageAllowed -> notEmpty() and ProductPropertiesScopeConguration.giftMessageAllowedScope= Scope::StoreView then self.redenedGiftMessageAllowed else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedGiftMessageAllowed -> notEmpty() and ProductPropertiesScopeConguration.giftMessageAllowedScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedGiftMessageAllowed else self.product.genericGiftMessageAllowed endif [22] ProductInStoreView :: visibleOnCatalog is the redenedVisibleOnCatalog at the current base scope level (the base scope level is dened by the visibleOnCatalogScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: visibleOnCatalog : Boolean body: if self.redenedVisibleOnCatalog -> notEmpty() and ProductPropertiesScopeConguration.visibleOnCatalogScope= Scope::StoreView then self.redenedVisibleOnCatalog else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedVisibleOnCatalog -> notEmpty() and ProductPropertiesScopeConguration.visibleOnCatalogScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedVisibleOnCatalog else self.product.genericVisibleOnCatalog endif [23] ProductInStoreView :: visibleOnSearch is the redenedVisibleOnSearch at the current base scope level (the base scope level is dened by the visibleOnSearchScope property, in product properties scope conguration). If theres no redenition at that level, it is the nearest upper redened value. Context ProductInStoreView :: visibleOnSearch : Boolean body: if self.redenedVisibleOnSearch -> notEmpty() and ProductPropertiesScopeConguration.visibleOnSearchScope= Scope::StoreView then

68

self.redenedVisibleOnSearch else if self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedVisibleOnSearch -> notEmpty() and ProductPropertiesScopeConguration.visibleOnSearchScope!= Scope::Global then self.product.productInWebsite -> select ( piw | piw.website.store.storeView -> includes ( self.storeView ) ).redenedVisibleOnSearch else self.product.genericVisibleOnSearch endif

Constraints
[1] A product is identied by its sku.

Context Product :: isIdentiedBySku() : Boolean body: Product.allInstances() -> isUnique(sku) [2] Each product should be related to all existing store views in the system.

Context Product :: isSpeciedInAllStoreViews() : Boolean body: Product.storeView -> includesAll( StoreView.allInstances() ) [3] Each product should be related to all existing websites in the system.

Context Product :: isSpeciedInAllWebsites() : Boolean body: Product.website -> includesAll( Website.allInstances() ) [4] The netPrice property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInWebsite :: netPriceIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.netPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.netPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.netPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.netPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.netPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.netPrice.isUndened() [5] The weight property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: weightIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.weight.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.weight.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.weight.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.weight.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.weight.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.weight.isUndened()

69

[6] If Product Properties Obligatoriness Conguration sets that isNewFrom is mandatory, each product should have a isNewFrom dened. Context ProductInStoreView :: isNewFromIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.isNewFromIsMandatory impliesnot(self.isNewFrom.isUndened()) [7] The isNewFrom property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: isNewFromIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.isNewFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.isNewFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.isNewFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.isNewFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.isNewFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.isNewFrom.isUndened() [8] If Product Properties Obligatoriness Conguration sets that isNewUntil is mandatory, each product should have a isNewUntil dened. Context ProductInStoreView :: isNewUntilIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.isNewUntilIsMandatory impliesnot(self.isNewUntil.isUndened()) [9] The isNewUntil property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: isNewUntilIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.isNewUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.isNewUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.isNewUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.isNewUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.isNewUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.isNewUntil.isUndened() [10] If Product Properties Obligatoriness Conguration sets that specialNetPrice is mandatory, each product should have a specialNetPrice dened. Context ProductInWebsite :: specialNetPriceIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.specialNetPriceIsMandatory impliesnot(self.specialNetPrice.isUndened()) [11] The specialNetPrice property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInWebsite :: specialNetPriceIsDenedOnlyForAssociatedProductTypes() : Boolean body:

70

let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.specialNetPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.specialNetPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.specialNetPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.specialNetPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.specialNetPrice.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.specialNetPrice.isUndened() [12] If Product Properties Obligatoriness Conguration sets that specialNetPriceFrom is mandatory, each product should have a specialNetPriceFrom dened. Context ProductInStoreView :: specialNetPriceFromIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.specialNetPriceFromIsMandatory impliesnot(self.specialNetPriceFrom.isUndened()) [13] The specialNetPriceFrom property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: specialNetPriceFromIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.specialNetPriceFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.specialNetPriceFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.specialNetPriceFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.specialNetPriceFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.specialNetPriceFrom.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.specialNetPriceFrom.isUndened() [14] If Product Properties Obligatoriness Conguration sets that specialNetPriceUntil is mandatory, each product should have a specialNetPriceUntil dened. Context ProductInStoreView :: specialNetPriceUntilIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.specialNetPriceUntilIsMandatory impliesnot(self.specialNetPriceUntil.isUndened()) [15] The specialNetPriceUntil property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: specialNetPriceUntilIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.specialNetPriceUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.specialNetPriceUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.specialNetPriceUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.specialNetPriceUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.specialNetPriceUntil.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.specialNetPriceUntil.isUndened()

71

[16] If Product Properties Obligatoriness Conguration sets that description is mandatory, each product should have a description dened. Context ProductInStoreView :: descriptionIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.descriptionIsMandatory impliesnot(self.description.isUndened()) [17] The description property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: descriptionIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.description.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.description.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.description.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.description.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.description.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.description.isUndened() [18] If Product Properties Obligatoriness Conguration sets that shortDescription is mandatory, each product should have a shortDescription dened. Context ProductInStoreView :: shortDescriptionIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.shortDescriptionIsMandatory impliesnot(self.shortDescription.isUndened()) [19] The shortDescription property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: shortDescriptionIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.shortDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.shortDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.shortDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.shortDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.shortDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.shortDescription.isUndened() [20] If Product Properties Obligatoriness Conguration sets that metaDescription is mandatory, each product should have a metaDescription dened. Context ProductInStoreView :: metaDescriptionIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.metaDescriptionIsMandatory impliesnot(self.metaDescription.isUndened()) [21] The metaDescription property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: metaDescriptionIsDenedOnlyForAssociatedProductTypes() : Boolean body:

72

let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.metaDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.metaDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.metaDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.metaDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.metaDescription.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.metaDescription.isUndened() [22] If Product Properties Obligatoriness Conguration sets that metaKeyword is mandatory, each product should have a metaKeyword dened. Context ProductInStoreView :: metaKeywordIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.metaKeywordIsMandatory impliesnot(self.metaKeyword.isUndened()) [23] The metaKeyword property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: metaKeywordIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.metaKeyword.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.metaKeyword.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.metaKeyword.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.metaKeyword.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.metaKeyword.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.metaKeyword.isUndened() [24] If Product Properties Obligatoriness Conguration sets that metaTitle is mandatory, each product should have a metaTitle dened. Context ProductInStoreView :: metaTitleIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.metaTitleIsMandatory impliesnot(self.metaTitle.isUndened()) [25] The metaTitle property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: metaTitleIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.metaTitle.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.metaTitle.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.metaTitle.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.metaTitle.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.metaTitle.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.metaTitle.isUndened()

73

[26] If Product Properties Obligatoriness Conguration sets that imageGalleryPath is mandatory, each product should have a imageGalleryPath dened. Context ProductInStoreView :: imageGalleryPathIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.imageGalleryPathIsMandatory impliesnot(self.imageGalleryPath.isUndened()) [27] The imageGalleryPath property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: imageGalleryPathIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.imageGalleryPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.imageGalleryPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.imageGalleryPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.imageGalleryPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.imageGalleryPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.imageGalleryPath.isUndened() [28] If Product Properties Obligatoriness Conguration sets that baseImagePath is mandatory, each product should have a baseImagePath dened. Context ProductInStoreView :: baseImagePathIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.baseImagePathIsMandatory impliesnot(self.baseImagePath.isUndened()) [29] The baseImagePath property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: baseImagePathIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.baseImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.baseImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.baseImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.baseImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.baseImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.baseImagePath.isUndened() [30] If Product Properties Obligatoriness Conguration sets that smallImagePath is mandatory, each product should have a smallImagePath dened. Context ProductInStoreView :: smallImagePathIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.smallImagePathIsMandatory impliesnot(self.smallImagePath.isUndened()) [31] The smallImagePath property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration.

74

Context ProductInStoreView :: smallImagePathIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.smallImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.smallImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.smallImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.smallImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.smallImagePath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.smallImagePath.isUndened() [32] If Product Properties Obligatoriness Conguration sets that thumbnailPath is mandatory, each product should have a thumbnailPath dened. Context ProductInStoreView :: thumbnailPathIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.thumbnailPathIsMandatory impliesnot(self.thumbnailPath.isUndened()) [33] The thumbnailPath property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: thumbnailPathIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.thumbnailPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.thumbnailPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.thumbnailPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.thumbnailPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.thumbnailPath.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.thumbnailPath.isUndened() [34] If Product Properties Obligatoriness Conguration sets that urlKey is mandatory, each product should have a urlKey dened. Context ProductInStoreView :: urlKeyIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.urlKeyIsMandatory impliesnot(self.urlKey.isUndened()) [35] The urlKey property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: urlKeyIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.urlKey.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.urlKey.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.urlKey.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.urlKey.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct))

75

implies self.urlKey.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.urlKey.isUndened() [36] If Product Properties Obligatoriness Conguration sets that isAvailableForGoogleCheckout is mandatory, each product should have a isAvailableForGoogleCheckout dened. Context ProductInStoreView :: isAvailableForGoogleCheckoutIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.isAvailableForGoogleCheckoutIsMandatory impliesnot(self.isAvailableForGoogleCheckout.isUndened()) [37] The isAvailableForGoogleCheckout property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: isAvailableForGoogleCheckoutIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.isAvailableForGoogleCheckout.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.isAvailableForGoogleCheckout.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.isAvailableForGoogleCheckout.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.isAvailableForGoogleCheckout.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.isAvailableForGoogleCheckout.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.isAvailableForGoogleCheckout.isUndened() [38] If Product Properties Obligatoriness Conguration sets that giftMessageAllowed is mandatory, each product should have a giftMessageAllowed dened. Context ProductInStoreView :: giftMessageAllowedIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.giftMessageAllowedIsMandatory impliesnot(self.giftMessageAllowed.isUndened()) [39] The giftMessageAllowed property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: giftMessageAllowedIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.giftMessageAllowed.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.giftMessageAllowed.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.giftMessageAllowed.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.giftMessageAllowed.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.giftMessageAllowed.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.giftMessageAllowed.isUndened() [40] If Product Properties Obligatoriness Conguration sets that visibleOnCatalog is mandatory, each product should have a visibleOnCatalog dened. Context ProductInStoreView :: visibleOnCatalogIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.visibleOnCatalogIsMandatory impliesnot(self.visibleOnCatalog.isUndened())

76

[41] The visibleOnCatalog property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: visibleOnCatalogIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.visibleOnCatalog.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.visibleOnCatalog.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.visibleOnCatalog.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.visibleOnCatalog.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.visibleOnCatalog.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.visibleOnCatalog.isUndened() [42] If Product Properties Obligatoriness Conguration sets that visibleOnSearch is mandatory, each product should have a visibleOnSearch dened. Context ProductInStoreView :: visibleOnSearchIsMandatoryIfDened() : Boolean body: ProductPropertiesObligatorinessConguration.visibleOnSearchIsMandatory impliesnot(self.visibleOnSearch.isUndened()) [43] The visibleOnSearch property is dened only in products that are from one of the types specied in Product Properties Type Association Conguration. Context ProductInStoreView :: visibleOnSearchIsDenedOnlyForAssociatedProductTypes() : Boolean body: let associatedTypes : Set(ProductType) = ProductPropertiesTypeAssociationConguration.descriptionAssociatedToProductType in (not (associatedTypes -> exists ( pt | pt = ProductType::Simple)) and self.product.oclIsTypeOf(SimpleProduct)) implies self.visibleOnSearch.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Grouped)) and self.product.oclIsTypeOf(GroupedProduct)) implies self.visibleOnSearch.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Congurable)) and self.product.oclIsTypeOf(CongurableProduct)) implies self.visibleOnSearch.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Virtual)) and self.product.oclIsTypeOf(VirtualProduct)) implies self.visibleOnSearch.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Downloadable)) and self.product.oclIsTypeOf(DownloadableProduct)) implies self.visibleOnSearch.isUndened() and (not (associatedTypes -> exists ( pt | pt = ProductType::Bundle)) and self.product.oclIsTypeOf(BundleProduct)) implies self.visibleOnSearch.isUndened()

Description

Product information is saved in a multi-level structure, depending on the scope. We detail, rstly, those properties that are dened globally (its value for a given product is the same anywhere in the system): sku: a unique identier for each distinct product that can be purchased. quantity: the products quantity in stock. stockStatus: even if some quantity of this product is in stock, the product can be set to Out of Stock. The following attributes redene, for this product, some generic stock conguration properties of the system. They are also dened globally. See the store conguration section for further information.

77

qtyToBecomeOutOfStock minQtyAllowedInShoppingCart maxQtyAllowedInShoppingCart backOrderPolicy notifyForQuantityBelow Most of the product properties works as follows: for a given product and property, a generic (global) value should be dened. But this value can be redened for each website or store view. The propertys value for a determinate product in a store view is calculated as the more specic redenition value. We can also tell the system to ignore some redenitions, by changing the corresponding property in the Scope Properties Conguration. We detail here only the most important: name netPrice: the net price of this product, without applying taxes or special offers. It can be redened at the website level, but not at the store view level. specialNetPrice: a different price that can be used as a temporary offer. It can be redened at the website level, but not at the store view level. weight: the products weight. Used for calculating the shipping costs in some shipping methods. . The Product Properties Type Association Conguration determine, for each property, that only the products that are from the types dened here can have this property dened. The Product Properties Scope Conguration determine, for each property, the lower scope where redenitions are taken into account when calculating the value for this property in a store view. The Product Properties Obligatoriness Conguration determine, for each property, if all products should mandatory have this property dened (at least at the global level) or not. A product is available in a Website if it can be purchased in the stores of this website. Magento establishes three types of relations between two different products: relatedProduct: meant to be purchased in addition to the item the customer is viewing. upSellProduct: items that customers would ideally buy instead of the product they are viewing. crossSellProduct: items that a customer who is buying the product in question might enjoy, but that are not directly related.

78

2.6.2
I

Product Options

Overview
Magento allows several options to be dened for each product, in order to offer multiple options of a product without needing to create many separate but very similar products

Schema Diagram

Derivation Rules
[1] OptionInStoreView :: name is the specic name dened for this store view, or the generic name if it is not dened. Context OptionInStoreView :: name : String body: if self.redenedName -> notEmpty() then self.redenedName else self.option.genericName endif [2] OptionValueInStoreView :: name is the specic name dened for this store view, or the generic name if it is not dened. Context OptionValueInStoreView :: name : String body:

79

if self.redenedName -> notEmpty() then self.redenedName else self.optionValue.genericName endif

Constraints
[1] Options are identied by its generic name and the product they belong to.

Context Option :: isIdentiedByItsGenericNameAndProduct() : Boolean body: Option.allInstances() -> isUnique(SetgenericName,product) [2] Options are also identied by its store view and name.

Context OptionInStoreView :: isIdentiedByItsStoreViewAndName() : Boolean body: OptionInStoreView.allInstances() -> isUnique(SetstoreView, name) [3] Option values are identied by its generic name.

Context OptionValue :: isIdentiedByItsGenericName() : Boolean body: OptionValue.allInstances() -> isUnique(genericName) [4] Option values are also identied by its store view and name.

Context OptionValueInStoreView :: isIdentiedByItsStoreViewAndName() : Boolean body: OptionValueInStoreView.allInstances() -> isUnique(SetstoreView, name) [5] Each option should be specied in all existing StoreViews in the system.

Context Option :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() ) [6] Each option value should be specied in all existing StoreViews in the system.

Context OptionValue :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() ) [7] An Option Value denes, for the options it belongs to, a relative or a xed increment, but not both. Context OptionValueInOption :: denesRelativeOrFixedIncrementButNotAll() : Boolean body: ( self.xedIncrement.isUndened() <> self.relativeIncrement.isUndened() ) [8] An option with user-dened-content denes a relative or a xed increment, but not both.

Context OptionWithContentDenedByCustomer :: denesRelativeOrFixedIncrementButNotAll() : Boolean body: ( self.xedIncrement.isUndened() <> self.relativeIncrement.isUndened() )

Description
Usually, there are products which are sold in different Options. The store administrator denes which are the options of each product. When a customer purchases it, the customer should dene which value does he give to the options of this product. Options with content dened by the customer allow the customer to give any textual or date value to this option. The sign and increments dene an extra amount of money that will be charged or deduced for giving a value to that option. For Options with predened content, the store administrator should dene several Option Values. When a customer purchases this product, he will choose one (or multiple) value(s) 80

for this option. Each Option Value can dene an increment that will be applied if the customer choses it. The system also requires information about: isRequired: denes if the customer must give a value to the product when purchasing it, or if it is optional. skuAppendix: used if the store administrator wants to associate different skus to the product depending on the options choosen. The skuAppendix will be added at the end of the originals product sku.

81

2.6.3
I

Product Types

Overview
Products offerded by the store can be classied into six types: Simple, Grouped, Congurable, Virtual, Downloadable and Bundle products.

Schema Diagram

82

Derivation Rules
[1] Product :: productType denotes the product type as an enumeration value.

Context Product :: productType : ProductType body: if self.oclIsTypeOf(SimpleProduct) then ProductType::Simple else if self.oclIsTypeOf(GroupedProduct) then ProductType::Grouped else if self.oclIsTypeOf(CongurableProduct) then ProductType::Congurable else if self.oclIsTypeOf(VirtualProduct) then ProductType::Virtual else if self.oclIsTypeOf(DownloadableProduct) then ProductType::Downloadable else ProductType::Bundle endif endif endif endif endif

Constraints

83

[1]

Bundle product items are identied by its name.

Context BundleProductItem :: isIdentiedByItsName() : Boolean body: BundleProductItem.allInstances() -> isUnique(name) [2] Downloadable items are identied by its name and downloadable product.

Context DownloadableItem :: isIdentiedByItsNameAndDownloadableProduct() : Boolean body: DownloadableItem.allInstances() -> isUnique(Setname,downloadableProduct) [3] Congurable attributes should have its isCongurable property set to true.

Context CongurableProduct :: hasOnlyCorrectCongurableAttributes() : Boolean body: self.congurableAttribute -> forAll ( ca | ca.isCongurable ) [4] A congurable product is able to rate the same attributes than all its associated products.

Context CongurableProduct :: isAssociatedToProductsWithTheSameAbleToRateAttributes() : Boolean body: self.associatedProduct -> forAll ( ap | ap.ableToRateAttribute -> select ( a | self.congurableAttribute -> includes(a) ) = self.congurableAttribute ) [5] Each simple product associated to a congurable product should have a different combination of the values assigned to its congurable attributes. Context CongurableProduct :: hasNoAssociatedProductsRepeated() : Boolean body: self.associatedProduct -> forAll ( p1, p2 | p1 <> p2 implies not ( p1.ableToRateAttribute -> select ( a | self.congurableAttribute -> includes(a) ).storeViewAttributeRating.attributeValue = p2.ableToRateAttribute -> select ( a | self.congurableAttribute -> includes(a) ).storeViewAttributeRating.attributeValue )) [6] Bundle product items have one and only one bundle product option as default.

Context BundleProductItem :: hasOnlyOneDefaultOption() : Boolean body: self.bundleProductOption -> select ( bpo | bpo.isDefault) -> size() = 1 [7] Bundle product options are simple, downloadable or virtual products.

Context BundleProductOption :: isAProductOfTheCorrectType() : Boolean body: self.product.oclIsTypeOf( SimpleProduct ) or self.product.oclIsTypeOf( DownloadableProduct ) or self.product.oclIsTypeOf( VirtualProduct ) [8] Grouped, Congurable, Virtual, Downloadable and Bundle products are not associated to the weight attribute. Context ProductPropertiesTypeAssociationConguration :: determineWeightOnlyForCorrectProductTypes() : Boolean body: self.weightAssociatedToProductType -> excludesAll ( Set ProductType::Grouped, ProductType::Congurable, ProductType::Bundle, ProductType::Virtual, ProductType::Downloadable ) [9] Grouped products are not associated to any attribute related to the price.

84

Context ProductPropertiesTypeAssociationConguration :: determinePriceRelatedAttributesOnlyForCorrectProductTypes() : Boolean body: self.netPriceAssociatedToProductType -> excludes ( ProductType::Grouped ) and self.specialNetPriceAssociatedToProductType -> excludes ( ProductType::Grouped ) and self.specialNetPriceFromAssociatedToProductType -> excludes ( ProductType::Grouped ) and self.specialNetPriceUntilAssociatedToProductType -> excludes ( ProductType::Grouped ) [10] Grouped are not associated to the price attribute, other product types are.

Context ProductPropertiesTypeAssociationConguration :: determineNetPriceOnlyForCorrectProductTypes() : Boolean body: self.netPriceAssociatedToProductType = SetProductType::Simple,ProductType::Congurable,ProductType::Downloadable,Prod [11] Grouped, Congurable, Virtual, Downloadable and Bundle products are not associated to the allowed gift message attribute. Context ProductPropertiesTypeAssociationConguration :: determineAllowedGiftMessageOnlyForCorrectProductTypes() : Boolean body: self.allowedGiftMessageAssociatedToProductType -> excludesAll ( Set ProductType::Grouped, ProductType::Congurable, ProductType::Bundle, ProductType::Virtual, ProductType::Downloadable ) [12] Groped, Congurable and Bundle Products do not have any inventory property, excepting the stock status. Context Product :: hasInventoryPropertiesOnlyIfNeeded() : Boolean body: ( self.oclIsTypeOf(GroupedProduct) or self.oclIsTypeOf(CongurableProduct) or self.oclIsTypeOf(BundleProduct) ) implies ( self.quantity.isUndened() and self.qtyToBecomeOutOfStock.isUndened() and self.minQtyAllowedInShoppingCart.isUndened() and self.maxQtyAllowedInShoppingCart.isUndened() and self.notifyForQuantityBelow.isUndened()and self.backOrderPolicy.isUndened() ) [13] Simple, Virtual and Downloadable Products must dene its quantity property.

Context Product :: hasQuantityPropertyWhenNeeded() : Boolean body: ( self.oclIsTypeOf(SimpleProduct) or self.oclIsTypeOf(VirtualProduct) or self.oclIsTypeOf(DownloadableProduct) ) implies self.quantity.isDened() [14] The sign and increment attributes are only dened if the downloadable product allows items to be purchased separatelly, but only one increment (xed or relative) is dened. Context DownloadableItem :: denesIncrementWhenNeeded() : Boolean body: if self.downloadableProduct.purchaseItemsSeparatelly = Status::Enabled then self.sign.isDened() and ( self.xedIncrement.isUndened() = self.relativeIncrement.isDened() ) else self.sign.isUndened() and self.xedIncrement.isUndened() and self.relativeIncrement.isUndened() endif [15] A Conguration denes a relative or a xed increment, but not both.

85

Context CongurationOfACongurableProduct :: denesRelativeOrFixedIncrementButNotAll() : Boolean body: ( self.xedIncrement.isUndened() = self.relativeIncrement.isDened() ) [16] The sign and increment attributes are only dened if the bundle product allows items to be purchased separatelly, but only one increment (xed or relative) is dened. Context BundleProductOption :: denesIncrementWhenNeeded() : Boolean body: if self.bundleProductItem.bundleProduct.priceMethod = PriceMethod::Fixed then self.sign.isDened() and ( self.xedIncrement.isUndened() = self.relativeIncrement.isDened() ) else self.sign.isUndened() and self.xedIncrement.isUndened() and self.relativeIncrement.isUndened() endif [17] Grouped Products and Bundle Products with the Fixed price do not have any Option.

Context Product :: hasOptionsOnlyIfNeeded() : Boolean body: self.oclIsTypeOf(GroupedProduct) or ( self.oclIsTypeOf(BundleProduct) and self.oclAsType(BundleProduct).priceMethod = PriceMethod::Fixed ) implies self.option -> isEmpty() [18] Grouped Products could not be associated to simple products with options.

Context GroupedProduct :: isNotAssociatedToProductsWithOptions() : Boolean body: self.associatedProduct -> forAll ( ap | ap.option -> isEmpty() ) [19] Congurable Products could not be associated to simple products with options.

Context CongurableProduct :: isNotAssociatedToProductsWithOptions() : Boolean body: self.associatedProduct -> forAll ( ap | ap.option -> isEmpty() ) [20] Bundle Products could not be associated to products with options.

Context BundleProduct :: isNotAssociatedToProductsWithOptions() : Boolean body: self.bundleProductItem.product -> forAll ( p | p.option -> isEmpty() )

Description
A Simple Product is an individual product, the attributes of which are determined by the store owner. A Grouped Product is a set of simple products that are sold together as a pack. A Congurable Product allows customers to congure some of its attributes when purchasing it (such as color, size...). The Congurable Product represents the abstract noncongurated product and is related to a set of Congured Products, each one representing one concrete available conguration. One or more congurableAttributes should be dened. The system will rely the conguration chosen by the customer to the simple associated product that matches it. Although this can be performed in a simpler way by using product options, this method allows the store administrator to keep track of the inventory for each congurated product. A Congurated Product is a Simple Product that can be sold as a concrete conguration of a Congurable Product. Virtual and Downloadable Products represent both non-physical items. The difference is that downloadable products are for digitized stuff that can be downloaded by the customer.The downloadable product record has a function to either point to a URL or le. Virtual products are more akin to a service. 86

Bundle products could be considered as a combination of grouped and congurable products. A Bundle Product has the following attributes: shippingMode: determines if the products will be shipped together or separately. priceMethod: determines the way the price will be calculated. specialNetPriceReduction: species a percentage reduction that will be applied to its original price to dene the products special net price. When a customer purchases a bundle product, he has to choose an option (or more) for each bundle product item. Magento saves the following information about bundle product items: name selectionType: determines if only one or more than bundle product options can be choosen by a customer when purchasing the product. isRequired: determines if no bundle product option can be choosen for this item. Each bundle product option is associated to one product. Magento also saves the following information: defaultQty: the default quantity that the customer will purchase of that product, if he chooses it. isQtyRedenable: determines if the customer can change the default quantity to purchase or not. isDefault: determines if this is the option selected by default for this bundle product item.

87

2.6.4
I

Categories

Overview
Products are grouped into categories which are arranged hierarchically.

Schema Diagram

Operations
[1] context Category def: allParents () : Set(Category) = self.parent -> union(self.parent.allParents())

Derivation Rules
[1] CategoryInStoreView :: name is the redenedName at the current base scope level, if it is dened, or the genericName of the category. Context CategoryInStoreView :: name : String body: if self.redenedName -> notEmpty() then self.redenedName else self.category.genericName

88

endif [2] CategoryInStoreView :: description is the redenedDescription at the current base scope level, if it is dened, or the genericDescription of the category. Context CategoryInStoreView :: description : String body: if self.redenedDescription -> notEmpty() then self.redenedDescription else self.category.genericDescription endif [3] CategoryInStoreView :: imagePath is the redenedImagePath at the current base scope level, if it is dened, or the genericImagePath of the category. Context CategoryInStoreView :: imagePath : String body: if self.redenedImagePath -> notEmpty() then self.redenedImagePath else self.category.genericImagePath endif [4] CategoryInStoreView :: pageTitle is the redenedPageTitle at the current base scope level, if it is dened, or the genericPageTitle of the category. Context CategoryInStoreView :: pageTitle : String body: if self.redenedPageTitle -> notEmpty() then self.redenedPageTitle else self.category.genericPageTitle endif [5] CategoryInStoreView :: metaKeyword is the redenedMetaKeyword at the current base scope level, if it is dened, or the genericMetaKeyword of the category. Context CategoryInStoreView :: metaKeyword : Set(String) body: if self.redenedMetaKeyword -> notEmpty() then self.redenedMetaKeyword else self.category.genericMetaKeyword endif [6] CategoryInStoreView :: metaDescription is the redenedMetaDescription at the current base scope level, if it is dened, or the genericMetaDescription of the category. Context CategoryInStoreView :: metaDescription : String body: if self.redenedMetaDescription -> notEmpty() then self.redenedMetaDescription else self.category.genericMetaDescription endif [7] CategoryInStoreView :: status is the redenedStatus at the current base scope level, if it is dened, or the genericStatus of the category. Context CategoryInStoreView :: status : Boolean body: if self.redenedStatus -> notEmpty() then self.redenedStatus else self.category.genericStatus

89

endif

Constraints
[1] Categories are identied by its generic name and its parent category.

Context Category :: isIdentiedByItsGenericNameAndParentCategory() : Boolean body: Category.allInstances() -> isUnique (SetgenericName,parent) [2] For a given store view, each category has a unique name.

Context StoreView :: doesNotHaveTwoCategoriesWithTheSameRedenedName() : Boolean body: self.categoryInStoreView -> isUnique (name) [3] Each category should be related to all existing store views in the system.

Context Category :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() ) [4] There are no cycles in category hierarchy.

Context Category :: isAHierarchy() : Boolean body: not self.allParents() -> includes(self)

Description
Magento groups products into categories which are arranged hierarchically. Categories have the following attributes: name: the categorys name. status: determines if the category is visible and accessible from the front end. urlKey: a relative URL path which can be used to acess automatically to the category page. description: the categorys description. imagePath: a path to the image that will be associated to the category. pageTitle: the title that will be shown in the categorys page. metaKeyword: meta keywords of the category. metaDescription: the meta description of the category. These attributes are dened for the whole system, but they can be redened at the store view level.

90

2.6.5
I

Attributes

Overview
Magento allows editing product attributes and creating new user-dened attributes.

Schema Diagram

91

Derivation Rules
[1] AttributeInStoreView :: name is the specic name dened for this store view, or the generic name if it is not dened. Context AttributeInStoreView :: name : String body: if self.redenedName -> notEmpty() then self.redenedName else self.attribute.genericName endif [2] Product :: ableToRateAttribute are the attributes that can be given a value for this product: all the system attributes and the simple attributes associated to the attribute set of this product. Context Product :: ableToRateAttribute : Set(Attribute) body: self.attributeSet.attribute

Constraints

92

[1]

Attributes are identied by its internal code.

Context Attribute :: isIdentiedByItsCode() : Boolean body: Attribute.allInstances() -> isUnique(code) [2] Attribute sets are identied by its name.

Context AttributeSet :: isIdentiedByItsName() : Boolean body: AttributeSet.allInstances() -> isUnique(name) [3] Each attribute should be specied in all existing StoreViews in the system.

Context Attribute :: isSpeciedInAllStoreViews() : Boolean body: Attribute.storeView -> includesAll( StoreView.allInstances() ) [4] Image attributes doesnt have those attributes dened. Other type of attributes should mandatory have it dened. Context Attribute :: hasTheUniqueAndRequiredPropertiesWhenNeeded() : Boolean body: if self.oclIsTypeOf(ImageAttribute) then self.hasUniqueValues -> isEmpty() and self.isRequired -> isEmpty() else self.hasUniqueValues -> notEmpty() and self.isRequired -> Empty() endif [5] A single valued enumeration attribute can be congurable only if its scope is set to global.

Context SingleValuedEnumerationAttribute :: canBeCongurableOnlyIfItIHasGlobalScope() : Boolean body: self.scope <> Scope::Global implies self.isCongurable = false

Description
Attributes are properties of products in the catalog. Users can create, delete them and dene some characteristics. For each attribute, users can set the following information: code: an internal code to identify this attribute. genericName: the name this attribute will be shown with in all store views. scope: the level at which the values of this attribute are shared. isComparable: determines whether the attribute values are usefull for customers to compare two or more products. hasUniqueValues: if it is true, the value selected or entered for this attribute for each product must be different. isRequired: if it is true, a value must be selected for this attribute for each product you create. associatedToProductType: the Product Types that will include this attribute. The name of the attribute can be redened for each storeView. Depending on the type of data that they represent, attributes can be classied into: TextualAttribute BooleanAttribute PriceAttribute DateAttribute 93

IntegerAttribute DecimalAttribute ImageAttribute EnumerationAttribute: can be rated only with a limited set of Literal Values. MultipleValuedEnumerationAttribute: an Enumeration Attribute that can be rated with more than one literal value at the same time. SingleValuedEnumerationAttribute: an Enumeration Attribute that can be rated with only one literal value at the same time. Most types of attributes allow dening a default value. Some of them have also specic properties: inputValidation: makes the system to check if the value assigned to this attribute matches an specic pattern, such as an email or an URL. It is only applied to Textual Attributes. isCongurable: determines if this attribute can be setted to congurable in a congurable product. It is only applied to Single Valued Enumeration Attributes. See the product types section for more information. Attributes can be assigned to one or more Attribute Sets. Each product is related to only one attribute set. For a given product, we are ableToRate all the attributes of its attribute set.

94

2.6.6
I

Attribute Values

Overview
Attributes should have a value for each product. Magento allows dening the scope in which a product value is shared.

Schema Diagram

Derivation Rules
[1] StoreViewAttributeRating :: attributeValue is the value redened for this store view. If it is not dened, the value redened in the website this store view belongs to. Inf it is not dened, the generic value. Context StoreViewAttributeRating :: attributeValue : AttributeValue body: if self.redenedAttributeValue -> notEmpty() and self.attribute.scope = Scope::StoreView then self.redenedAttributeValue else if self.storeView.store.website.websiteAttributeRating -> select ( war | war.product = self.product and war.attribute = self.attribute ).redenedAttributeValue -> notEmpty() and self.attribute.scope != Scope::Global then self.storeView.store.website.websiteAttributeRating -> select ( war | war.product = self.product and war.attribute = self.attribute ).redenedAttributeValue

95

else self.product.globalAttributeRating -> select ( gar | gar.attribute = self.attribute).genericAttributeValue endif [2] LiteralValueInStoreView :: name is the specic name dened for this store view, or the generic name if it is not dened. Context LiteralValueInStoreView :: name : String body: if self.redenedName -> notEmpty() then self.redenedName else self.attribute.genericName endif

Constraints
[1] Textual values are identied by its value.

Context TextualValue :: isIdentiedByItsValue() : Boolean body: TextualValue.allInstances() -> isUnique(value) [2] Boolean values are identied by its value.

Context BooleanValue :: isIdentiedByItsValue() : Boolean body: BooleanValue.allInstances() -> isUnique(value) [3] Price values are identied by its value.

Context PriceValue :: isIdentiedByItsValue() : Boolean body: PriceValue.allInstances() -> isUnique(value) [4] Date values are identied by its value.

Context DateValue :: isIdentiedByItsValue() : Boolean body: DateValue.allInstances() -> isUnique(value) [5] Integer values are identied by its value.

Context IntegerValue :: isIdentiedByItsValue() : Boolean body: IntegerValue.allInstances() -> isUnique(value) [6] Decimal values are identied by its value.

Context DecimalValue :: isIdentiedByItsValue() : Boolean body: DecimalValue.allInstances() -> isUnique(value) [7] Image values are identied by its value.

Context ImageValue :: isIdentiedByItsImagePath() : Boolean body: ImageValue.allInstances() -> isUnique(path) [8] to. Enumeration values are identied by its generic name and the enumeration attribute it belongs

Context EnumerationValue :: isIdentiedByItsGenericNameAndAttribute() : Boolean body: EnumerationValue.allInstances() -> isUnique(SetgenericName, enumerationAttribute) [9] Multiple enumeration values are identied by its iset of enumeration values.

96

Context MultipleEnumerationValue :: isIdentiedByItsSetOfEnumerationValues() : Boolean body: MultipleEnumerationValue.allInstances() -> isUnique(enumerationValue) [10] A literal value is associated to all the storeviews.

Context EnumerationValue :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll ( StoreView.allInstances() ) [11] A product and attribute can only participate in the attribute rating relationship if the attribute is an able to rate attribute of this product. Context Product :: isOnlyRatedForItsAbleToRateProducts() : Boolean body: self.ableToRateAttribute -> includesAll ( self.globalAttributeRating.attribute ) and self.ableToRateAttribute -> includesAll ( self.websiteAttributeRating.attribute ) and self.ableToRateAttribute -> includesAll ( self.storeViewAttributeRating.attribute ) [12] All the able to rate attributes have a global attribute rating, one website rating for each website and one store view rating for each store view in the system. Context Product :: hasAGlobalWebsiteAndStoreViewRatingForAllAbleToRateProducts() : Boolean body: self.globalAttributeRating.attribute -> includesAll ( self.ableToRateAttribute ) and self.ableToRateAttribute -> forAll ( a | self.websiteAttributeRating -> select ( gar | gar.attribute = a ).website -> includesAll (Website.allInstances()) ) and self.ableToRateAttribute -> forAll ( a | self.storeViewAttributeRating -> select ( gar | gar.attribute = a ).storeView -> includesAll (StoreView.allInstances()) ) [13] A product has given a value to each required attribute it is related to.

Context Product :: hasARatingForAllRequiredAttributes() : Boolean body: self.ableToRateAttribute -> forall ( av | (av.isRequired.notEmpty() and av.isRequired) implies self.storeViewAttributeRating -> forall ( sar | sar.storeViewRatedAttribute=av implies sar.attributeValue.notEmpty() ) ) [14] If an attribute is set to be unique, there are no two different products that assign it the same value, even in different store views. Context Attribute :: ratingsRespectTheUniqueConstraint() : Boolean body: (self.hasUniqueValues -> notEmpty() andself.hasUniqueValues) implies self.storeViewAttributeRating -> forall ( sar1, sar2 | sar1.attributeValue = sar2.attributeValue implies ar1.product = ar2.product ) [15] Only text eld values are given to a text eld attribute.

Context TextualAttribute :: isFilledWithTextualValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( TextualValue ) ) [16] Only price values are given to a price attribute.

97

Context PriceAttribute :: isFilledWithPriceValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( PriceValue ) ) [17] Only date values are given to a date attribute.

Context DateAttribute :: isFilledWithDateValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( DateValue ) ) [18] Only boolean values are given to a boolean attribute.

Context BooleanAttribute :: isFilledWithBooleanValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( BooleanValue ) ) [19] Only integer values are given to a integer attribute.

Context IntegerAttribute :: isFilledWithIntegerValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( IntegerValue ) ) [20] Only decimal values are given to a decimal attribute.

Context DecimalAttribute :: isFilledWithDecimalValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( DecimalValue ) ) [21] Only image values are given to an image attribute.

Context ImageAttribute :: isFilledWithImageValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies v.oclIsTypeOf( ImageValue ) ) [22] Only single enumeration values are given to a single valued enumeration attribute, and its value options are options of the attribute. Context SingleValuedEnumerationAttribute :: isFilledWithSingleEnumerationValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies (v.oclIsTypeOf( EnumerationValue ) and self.allowedValue -> includes ( v) )) [23] Only multiple enumeration values are given to a multiple valued enumeration attribute, and its value options are options of the attribute. Context MultipleValuedEnumerationAttribute :: isFilledWithMultipleEnumerationValues() : Boolean body: self.storeViewAttributeRating.attributeValue -> forall ( v | v.isDened() implies (v.oclIsTypeOf( MultipleEnumerationValue ) and self.allowedValue -> includesAll ( v.oclAsType(MultipleEnumerationValue).enumerationValue )

98

))

Description
In Magento, users assign a global value to each couple product - attribute. But they can redene this value for each website or storeview. Some attribute properties restrict the way this values are assigned: scope: dene at which level we can rate this attribute. If it is set to Global, no store view and website redenitions are not taken into account. If it is Website, only the redenitions at the website level are taken into account. With a Store View scope, all redenitions are taken into account. hasUniqueValues: if true, there can not be two products where this attribute is rated with the same value. isRequired: if true, each product that has this attribute should give it a value. isComparable: indicates whether the attribute can be used for customers to compare two different products. Global, Website and Storeview Attribute Ratings are the fact that an attribute has a value in a specic scope. Each one can have a generic value or its redenition associated. For a given product, attribute and store view, the attribute value is the more specic dened value, taking into account only the redenitions specied by the scope property of this attribute. Depending on the type of data they represent, there are several types of Attribute Values. Textual Value Boolean Value Price Value Date Value Integer Value Decimal Value Image Value: where the le path of the image is specied. Single Enumeration Value: represents the choose of one literal value, from those specied by the corresponding single enumeration attribute. Multiple Enumeration Value: represents the choose of a non-empty set of literal values, from those specied by the corresponding multiple enumeration attribute. Literal values have a generic name, that can be redened for a given store view.

99

2.6.7
I

Price Rules

Overview
Magento allows moding the nal product prices depending on the quantity of products ordered or its properties.

Schema Diagram

100

Derivation Rules
[1] ShoppingCartPriceRuleInStoreView :: label is the redenedLabel at the current base scope level, if it is dened, or the genericLabel of the category. Context ShoppingCartPriceRuleInStoreView :: label : String body: if not(self.redenedLabel.isUndened()) then self.redenedLabel else self.category.genericLabel endif [2] ShoppingCartPriceRule :: timesUsed is the number of times the rule has been used by anyone. Context ShoppingCartPriceRule :: timesUsed : String body: self.useOfShoppingCartPriceRule.timesUsed -> sum()

Constraints
[1] A shopping cart price rule is identied by its product and quantity.

Context TierPrice :: isIdentiedByItsProductAndQuantity() : Boolean body: TierPrice.allInstances() -> isUnique(Tuplep:product,q:quantity) [2] A catalog price rule is identied by its name.

Context CatalogPriceRule :: isIdentiedByItsName() : Boolean body: CatalogPriceRule.allInstances() -> isUnique(name) [3] A catalog price rule is identied by its priority.

Context CatalogPriceRule :: isIdentiedByItsPriority() : Boolean body: CatalogPriceRule.allInstances() -> isUnique(priority) [4] A shopping cart price rule is identied by its name.

Context ShoppingCartPriceRule :: isIdentiedByItsName() : Boolean body: ShoppingCartPriceRule.allInstances() -> isUnique(name) [5] A shopping cart price rule is identied by its priority.

Context ShoppingCartPriceRule :: isIdentiedByItsPriority() : Boolean body: ShoppingCartPriceRule.allInstances() -> isUnique(priority) [6] A shopping cart price rule in a store view is identied by its label and store view.

Context ShoppingCartPriceRuleInStoreView :: isIdentiedByItsLabelAndStoreView() : Boolean body: ShoppingCartPriceRuleInStoreView.allInstances() -> isUnique(Tuplel:label,s:storeView) [7] Each shopping cart price rule should be specied in all existing store views in the system.

Context ShoppingCartPriceRule :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() ) [8] The discountQtyStep property is only dened if the apply method selected is Percentage or BuyXGetY.

101

Context ShoppingCartPriceRule :: hasTheDiscountQtyStepDenedWhenNeeded() : Boolean body: not(self.discountQtyStep.isUndened()) implies ( self.method = ShoppingCartRuleDiscountMethod::Percentage or self.method = ShoppingCartRuleDiscountMethod::BuyXGetY ) [9] A shopping cart price rule can not be totally used more times than the total uses dened.

Context ShoppingCartPriceRule :: isNotUsedMoreThanPermitted() : Boolean body: self.maxUses >= self.useOfShoppingCartPriceRule.timesUsed -> sum() [10] A shopping cart price rule can not be used by a customer more times than the total uses per customer dened. Context ShoppingCartPriceRule :: isNotUsedMoreThanPermittedToOneCustomer() : Boolean body: self.useOfShoppingCartPriceRule -> forAll ( usc | self.maxUsesPerCustomer >= usc.timesUsed) [11] Fixed tier prices are not applied to Bundle and Grouped Products

Context FixedTierPrice :: isAppliedToProductsOfTheCorrectType() : Boolean body: not(self.product.oclIsTypeOf(BundleProduct) or self.product.oclIsTypeOf(GroupedProduct)) [12] Relative tier prices are only applied to Bundle Products

Context RelativeTierPrice :: isAppliedToProductsOfTheCorrectType() : Boolean body: self.product.oclIsTypeOf(BundleProduct)

Description
A Tier Price determines that a product will be priced differently for higher quantities. If a Customer of a selected Customer Group purchases more unities of a product than the established quantity, each unit will be priced at the new dened price (for Fixed Tier Prices) or the percentage reduction will be applied (for Relative Tier Prices). For multiple tier denition, they take precedence from the highest to lowest quantity. Catalog Price Rules are applied to a product, if it meets the dened condition. Shopping Cart Price Rules are applied to all products in a shopping cart, when the shopping cart meet the dened condition. These conditions state values for the product attributes to be selected or quantities of products to be purchased in a shopping cart. Rules will only be applied in the dened websites, as well as for customers belonging to the dened customer groups. Magento saves the following information about price rules: name: the name of the rule. description: a description of the rule. status: whether the rule is currently enabled or not. priority: denes the order the rules will be applied. inEffectFrom: the beggining of the data range for the promotion to be in effect. If empty, the rule will be enabled as soon as it is created.

102

inEffectUntil: the end of the data range for the promotion to be in effect. If empty, the rule will be enabled until it is deleted. amount: the numerical value of the discount, which can either a percentage or xed monetary amount, depending on the apply method dened. stopFurtherRules: will cause the system to ignore any other existing rules with a lower priority once this rule has been calculated. condition: the condition a product or shopping cart should meet in order that the price rule can be applied . Additional attributes should be dened for Shopping Cart Price Rules: couponCode: if dened, the rule will only be applied if the customer enters this code when placing an order. If no code is dened, the application of the rule depends only on its conditions. maxUses: the maximum amount of thimes the rule can be used total. Theres no limit if it is no dened. maxUsesPerCustomer: the maximum amount of times the Rule can be used per customer, whether or not you require a coupon code. If empty, there will be no limit.The UseOfShoppingCartPriceRule::timesUsed property indicates the number of times the rule has been used by a customer. timesUsed: the number of times the rule has been used by anyone. Derived Attribute. maxQuantity: limits how many units of each line item in the shopping cart will receive this discount. discountQtyStep: only dened if the apply method is Percentage or BuyXGetY, determines the quantities that your customers will have to purchase in order to receive a percentage discount or the offered free units, respectively. freeShippingMethod: determines whether the rule can be combined with a free shipping offer, if it is offered. If MatchingItems is selected, only the products that match the rules condition will be able to ship for free. For AllItems, that will be also applied for other products in the shopping cart. itemLevelCondition: restricts the application of the dened discounts to the products that meets it. If it is no dened, the rule is applied to all the products in the shopping cart. For shopping cart price rules, a discount applying method should be chosen from the following: Percentage: substracts, for each product, the discount amount as a percentage of the original price. If a discountQtyStep is dened, the discount will be placed only to a reduced quantity of products, this quantity dened as the greatest factor of discountQtyStep that is below the purchased quantity. Fixed: substracts, for each product, the discount amount from the price of each product. FixedForWholeCart: as the Fixed method, but it is applied only once to the total cart amount. BuyXGetY: offers a quantity of free items, for each product, determined by the discount amount property. The number of given units is dened by the discountQtyStep property. A generic label is dened to show a shopping cart price rule to customers, which can be redened at the store view level. In catalog price rules, the following discount applying methods could be chosen: 103

SetAsFixed: sets the nal discounted price to the discount amount. SubstractFixed: substracts the discount amount from the original price. SetAsPercentage: sets the nal discounted price to the discount amount percentage of the original price. SubstractPercentage: substracts the discount amount as a percentage of the original price.

104

2.7 Additional Activities


2.7.1
I

Product Tags

Overview
Tags are one-word descriptors that customers can add to products.

Schema Diagram

Derivation Rules
[1] TagInStoreView :: popularity is the number of times the tag has been applied in this storeView, adding the base popularity. Context TagInStoreView :: popularity : Integer body: self.basePopularity + self.tag.productTagging -> select ( t | t.storeView = self.storeView ) -> size()

Constraints
[1] Tags are identied by its name.

Context Tag :: isIdentiedByItsName() : Boolean body: Tag.allInstances() -> isUnique(name) [2] Each tag should be related to all existing store views in the system.

105

Context Tag :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() )

Description
Tags act as keywords. Tags help Customers to organize and remember the products that they have seen. System saves the following information for tags: name: the description word itself. . status: Pending tags are those recently added by costumers. Administrators can after change its status to Approved or Disabled. A ProductTagging is the fact that a Customer has assigned a Tag to a Product in a Store View. Magento saves the time this assignation was made. Administrators can also add Tags to Products. In this case, only the Product tagged and the selectionned tag are saved. Some tag properties can be set at the store view scope: basePopularity: is added to the number of times the tag is assigned to calculate its popularity. popularity: used by the system to emphasize the most used tags. Derived Attribute.

106

2.7.2
I

Product Reviews

Overview
Customers can write reviews so that other users may read evaluations of a product.

Schema Diagram

Derivation Rules
[1] PropertyInStoreView :: name is the name redened in this store view. If it is not dened, the generic name. Context PropertyInStoreView :: name : String body: if self.redenedName -> notEmpty() then self.redenedName else self.property.genericName endif

Constraints
[1] Properties are identied by its generic name.

Context Property :: isIdentiedByItsGenericName() : Boolean body: Property.allInstances() -> isUnique(genericName)

107

[2]

Within a store view, properties should also be identied by its name.

Context PropertyInStoreView :: isIdentiedByItsStoreViewAndName() : Boolean body: PropertyInStoreView.allInstances() -> isUnique(Setname,storeView) [3] Reviews are identied by its author nick name and its text.

Context Review :: isIdentiedByItsAuthorNickNameAndText() : Boolean body: Review.allInstances() -> isUnique(SetauthorNickName,text) [4] Each property should be related to all existing store views in the system.

Context Property :: isSpeciedInAllStoreViews() : Boolean body: self.storeView -> includesAll( StoreView.allInstances() )

Description
A Review is a customer evaluation of a product. Magento takes into account the following information about reviews: authorNickName: a name that the autor of the review chooses, with no restriction, to identicate himself ahead of the other users. title: the title of the review. text: the text of the review. status: Pending reviews are those recently added by Costumers. Administrators can after change its status to Approved or NotApproved. createdAt: the time the review was made. storeViewWhereIsVisible: the store views where this review is visible. When it is created, it is only visible in the store view it was created, but administrators can change it after. productReviewed: the product that is reviewed. user: the costumer or administrator that has made the review. Reviews can be made by not registered costumers. In this case, no user is associated to it. Magento allows us to dene properties that the user will be able to rate for a product.Properties have a genericName that can be redened for each store view. We can set properties to be not visible in a store view. A Property Score assigns a value to a property for a product. When a review is placed, an score should be provided for each property which is visible in the store view it was made. As properties visibility can be modied later, this constraint could not be respected after editing a property.

108

2.7.3
I

Buying Process Information

Overview
Magento allows customers to save information to support the buying process: wished products, product comparison and alerts, etc.

Schema Diagram

109

Derivation Rules
[1] ActivityInfoOfSessionInStoreView :: readyToCompareProduct are the explicit ready to compare products, if the catalog conguration sets its scope to StoreView, or the websites ready to compare products otherwise. Context ActivityInfoOfSessionInStoreView :: readyToCompareProduct : Set(Product) body: let currentWebsite : Website = self.sessionWithInfoAbout.storeView.store.website in if currentWebsite.CatalogCongurationInWebsite.recentlyViewedComparedProductsScope = Scope::StoreView then self.explicitReadyToCompareProduct else currentWebsite.activityInfoOfSessionInWebsite -> any ( siw | siw.sessionWithInfoAbout = self ).explicitReadyToCompareProduct endif [2] ActivityInfoOfSessionInStoreView :: recentlyComparedProduct are the explicit recently compared products, if the catalog conguration sets its scope to StoreView, or the websites recently compared products otherwise. Context ActivityInfoOfSessionInStoreView :: recentlyComparedProduct : Set(Product) body: let currentWebsite : Website = self.sessionWithInfoAbout.storeView.store.website in if currentWebsite.CatalogCongurationInWebsite.recentlyViewedComparedProductsScope = Scope::StoreView then self.explicitRecentlyComparedProduct else currentWebsite.activityInfoOfSessionInWebsite -> any ( siw | siw.sessionWithInfoAbout = self ).explicitRecentlyComparedProduct endif [3] ActivityInfoOfSessionInStoreView :: readyRecentlyViewedProduct are the explicit ready to compare products, if the catalog conguration sets its scope to StoreView, or the websites recently viewed products otherwise. Context ActivityInfoOfSessionInStoreView :: readyRecentlyViewedProduct : Set(Product) body: let currentWebsite : Website = self.sessionWithInfoAbout.storeView.store.website in if currentWebsite.CatalogCongurationInWebsite.recentlyViewedComparedProductsScope = Scope::StoreView then self.explicitRecentlyViewedProduct else currentWebsite.activityInfoOfSessionInWebsite -> any ( siw | siw.sessionWithInfoAbout = self ).explicitRecentlyViewedProduct endif

I
[1]

Constraints
No wished products are registered if the wish list is not enabled for this website.

Context ActivityInfoOfCustomerInWebsite :: denesWishedProductsOnlyIfAllowed() : Boolean body: self.websiteWithInfoAbout.wishlistCongurationInWebsite.status = Status::Disabled implies self.wishedProduct -> isEmpty() [2] A ready to compare product can not match with any recently compared product.

Context ActivityInfoOfSessionInStoreView :: hasNotMatchingComparedAndRecentlyComparedProducts() : Boolean body: self.recentlyComparedProduct -> excludesAll ( self.readyToCompareProduct )

110

[3]

A ready to compare product can not match with any recently compared product.

Context ActivityInfoOfCustomerInStoreView :: hasNotMatchingComparedAndRecentlyComparedProducts() : Boolean body: self.recentlyComparedProduct -> excludesAll ( self.readyToCompareProduct ) [4] A ready to compare product can not match with any recently compared product.

Context ActivityInfoOfCustomerInWebsite :: hasNotMatchingComparedAndRecentlyComparedProducts() : Boolean body: self.recentlyComparedProduct -> excludesAll ( self.readyToCompareProduct ) [5] The number of uses of the Tell to a friend feature is not greater than the maximum uses allowed by the system conguration. Context ActivityInfoOfSessionInStoreView :: hasNotUsedTellToAFriendTooMuch() : Boolean body: self.usesOfTellToFriendInLastHour <= self.storeViewWithInfoAbout.tellToAFriendCongurationInStoreView.maxUsesPerHour [6] The customers saved number of uses of the Tell to a friend feature is not greater than the maximum uses allowed by the system conguration. Context ActivityInfoOfCustomerInStoreView :: hasNotUsedTellToAFriendTooMuch() : Boolean body: self.usesOfTellToFriendInLastHour <= self.storeViewWithInfoAbout.tellToAFriendCongurationInStoreView.maxUsesPerHour

Description
When a customer, either registered or not, uses the system, some information about his activity is generated: it is called the activity info of the session: readyToCompareProducts: Magento offers a useful feature to quickly compare product attribute information in a side-by-side view. Those are the products the Customer choose to compare. recentlyComparedProducts: the products that the customer has recently removed from the ready to compare list. recentlyViewedProducts: the products for which the customers have recently viewed the page. When a registered Customer goes ofine, its last activity info is saved to be restored the next time he returns online. The activity info can be shared at the website or the store view level, depending on the Catalog Conguration settings. The system also keeps track of usesOfTellToAFriendInLastHour: the number of times the customer has used the Tell to a friend feature in the last hour. wishedProducts: designated by registered customers to indicate that they wish to purchase them (or have someone purchase for them) at a later date. A comment can be added by the Customer, explaining why does he wish that item. productSubscribedForPriceAlert: customers will receive an e-mail when the price of this product is changed. productSubscribedForStockAlert: customers will receive an e-mail when this product goes back in stock. 111

Wishlist and product alerts are only allowed for registered customers, while the uses of tell to friend are resetted when the corresponding session is closed.

112

2.7.4
I

Newsletters

Overview
Magento allows store owners to send emails and product notications to customers.

Schema Diagram

Derivation Rules
[1] NewsletterSubscription :: email is the provided email, if it is dened, or the customers own email, otherwise. Context NewsletterSubscription :: email : Email body:

113

if self.oclIsTypeOf(AnonymousNewsletterSubscription) then self.oclAsType(AnonymousNewsletterSubscription).providedEMail else if not(self.providedEMail.isUndened()) then self.oclAsType(CustomerNewsletterSubscription).providedEMail else self.oclAsType(CustomerNewsletterSubscription).customer.email endif

Constraints
[1] Newsletter templates are identied by its name.

Context NewsletterTemplate :: isIdentiedByItsName() : Boolean body: NewsletterTemplate.allInstances() -> isUnique (name) [2] Newsletters are identied by its subject and message.

Context Newsletter :: isIdentiedByItsSubjectAndMessage() : Boolean body: Newsletter.allInstances() -> isUnique (Setsubject,message) [3] Newsletters are identied by its email and store view.

Context AnonymousNewsletterSubscription :: isIdentiedByItsEmailAndStoreView() : Boolean body: AnonymousNewsletterSubscription.allInstances() -> isUnique (Tuplec:eMail,s:storeView) [4] Newsletters are identied by its customer and store view.

Context CustomerNewsletterSubscription :: isIdentiedByItsCustomerAndStoreView() : Boolean body: CustomerNewsletterSubscription.allInstances() -> isUnique (Tuplec:customer,s:storeView) [5] A customer could not have two newsletter subscriptions from the same store view.

Context Customer :: isNotSubscribedTwiceInAStoreView() : Boolean body: self.customerNewsletterSubscription -> isUnique (storeView) [6] A newsletter can not have been sended to more customers or visitors than the total subscriptions that are made to it. Context Newsletter :: hasTheCorrectProcessedSendings() : Boolean body: self.processedSendigs <= self.storeView.newsletterSubscription -> asSet() -> size()

Description
Customers, registered or not, can subscribe themselves to the store newsletter. email: the email address where the newsletter will be sent. Registered customers can optionally specify a different email address, if not its own address is taken. status: the subscription can be temporally disabled, without deleting the subscription information. To start sending newsletters, Newsletter Templates should be created rst. Those are its properties: name: the templates name. subject: the subject of the email that will be sent to your customers for a newsletter using this template. 114

senderName: the name of the sender of the email that will be sent to your customers for a newsletter using this template. senderEmail: the email address of the sender of the email that will be sent to your customers for a newsletter using this template. message: the body of your email for a newsletter using this template. createdAt: the time the template was created. lastUpdatedAt: the last time the template was updated. The newsletter is created from a template. The name, subject and sender name and email are generally suposed to be the same, but can be changed. Additional properties are dened: queueStartedAt: the time the system will start sending the newsletter. If not dened, the system starts sending the newsletter from the moment it is created. processedSendings: the number of customers or visitors where the newsletter has been sent. storeView: this newsletter will be sent to all the customers or visitors that have been subscribed for the newsletter at this store view. status A newsletter problem reports a problem that the system had sending the newsletter. Magento saves the newsletter where this error has been produced and, if needed, the corresponding subscription. For example, a newsletter sent to an erroneous e-mail address will appear here. id: identies the problem report. code: identies the type of error that have been succeded. text: a human friendly explanation of the error.

115

2.8 Online Catalog


2.8.1
I

Shopping Carts

Overview
Customers can add or remove products from their shopping carts while they are navigating the online store.

Schema Diagram

Derivation Rules
[1] ShoppingCart :: total the amount the customer will pay for all products in the shopping cart.

Context ShoppingCart :: total : Integer body: self.shoppingCartItem.total -> sum() [2] ShoppingCart :: currentStoreView Is the store view that will be used to calculate the prices and discounts that will be applied to the purchased items. Context ShoppingCart :: currentStoreView : StoreView body: if self.oclIsTypeOf(AnonymousShoppingCart) then self.oclAsType(AnonymousShoppingCart).anonymousSession.storeView else if self.oclIsTypeOf(CustomerShoppingCart) then self.oclAsType(CustomerShoppingCart).customer.customerSession.storeView

116

else self.oclAsType(AdministrationShoppingCart).storeView endif endif [3] ShoppingCart :: purchasingCurrency Is the currency used to buy the products in the shopping cart. Context ShoppingCart :: purchasingCurrency : Currency body: if self.oclIsTypeOf(AnonymousShoppingCart) then self.oclAsType(AnonymousShoppingCart).anonymousSession.currentCurrency else if self.oclIsTypeOf(CustomerShoppingCart) then self.oclAsType(CustomerShoppingCart).customer.customerSession.currentCurrency else self.oclAsType(AdministrationShoppingCart).currency endif endif [4] ShoppingCart :: customerGroup will be used to dene some characteristics (as taxes) that affect the nal amount that the user will pay for this products. For Anonymous Shopping Carts the "Not Logged In" group is applied, while Customer Shopping Carts use the group of its related customer. For Administration Shopping Carts, the group is explicitly selected. Context ShoppingCart :: customerGroup : CustomerGroup body: if self.oclIsTypeOf(AnonymousShoppingCart) then CustomerGroup.allInstances() -> any ( c | c.name = NotLoggedIn ) else if self.oclIsTypeOf(CustomerShoppingCart) then self.oclAsType(CustomerShoppingCart).customer.customerGroup else if self.oclAsType(AdministrationShoppingCart).redenedCustomerGroup -> notEmpty() then self.oclAsType(AdministrationShoppingCart).redenedCustomerGroup else self.oclAsType(AdministrationShoppingCart).customer.customerGroup endif endif endif [5] AdministrationShoppingCart :: customerEMail Is the redened customer eMail, if dened, or the eMail of the associated customer. Context AdministrationShoppingCart :: customerEMail : EMail body: if self.redenedCustomerEMail.isDened() then self.redenedCustomerEMail else self.customer.eMail endif

Constraints
[1] An anonymous shopping cart is identied by its anonymous session.

Context AnonymousShoppingCart :: isIdentiedByItsAnonymousSession() : Boolean body: AnonymousShoppingCart.allInstances() -> isUnique(anonymousSession) [2] A customer shopping cart is identied by its customer.

Context CustomerShoppingCart :: isIdentiedByItsCustomer() : Boolean body: CustomerShoppingCart.allInstances() -> isUnique(customer) [3] An administration shopping cart is identied by its customer, the store view where is placed and the administrator who places it. Context AdministrationShoppingCart :: isIdentiedByItsCustomerStoreViewAndAdministrator() : Boolean body: AdministrationShoppingCart.allInstances() -> isUnique(Setcustomer, storeView, administrator)

117

[4]

The shopping cart was not created in the future.

Context CustomerShoppingCart :: hasACorrectCreatedAtDate() : Boolean body: self.createdAt <= Now() [5] The time the user did his last update on the shopping cart should be between the time the shopping cart was created and now. Context CustomerShoppingCart :: hasACorrectUpdatedAtDate() : Boolean body: self.updatedAt >= self.createdAt and self.updatedAt <= Now()

Description
Shopping Carts contain the products chosen by customers from the online catalog. A Shopping Cart is anonymous until the Customer logs in. At this moment, if the Customer didnt have a previous Customer Shopping Cart, the Anonymous Shopping Cart becomes a Customer Shopping Cart. Otherwise, the anonymous Shopping Cart is removed from the system and their Products are added to the previous Customer Shopping Cart. If a Customer leaves a Session with a non-empty Customer Shopping Cart, then the cart will be automatically restored in his next session. Moreover, Anonymous Shopping Carts can only exist in the context of a Session, and they are automatically removed when the Session expires. Administration Shopping Carts are used when Administrators use the system to register an Order for a Customer, that has normally asked for it in an ofine way. The prices, discounts and taxes will be calculated as if the Order was placed using the specied store view. In addition of the derived attributes, which are described by its derivation rules, Magento saves the following information about Shopping Carts: giftMessage: a message that will be delivered to the person that receives the products added to the cart, if an order for it is nally placed. couponCode: a literal code that can enable the application of a Shopping Cart Price Rule that matches it. For Customer Shopping Carts, the following information is also saved: createdAt: the time the cart was created. updatedAt: the last time a product was added, edited or removed from the shopping cart. When an order corresponding to a Shopping Cart is conrmed, the Shopping Cart is removed from the system.

118

2.8.2
I

Shopping Cart Items

Overview
Each different Product added to a Shopping Cart is a Shopping Cart Item.

Schema Diagram

Operations
[1] context ShoppingCartItem def: calculateNetPrice (currentProduct : Product) : Money = currentProduct.productInWebsite -> any ( piw | piw.website = self.shoppingCart.currentStoreView.store.website).netPrice [2] context ShoppingCartItem def: calculateSpecialNetPrice (currentProduct : Product) : Money = let productInTheCurrentWebsite:ProductInWebsite = currentProduct.productInWebsite -> any ( piw | piw.website = self.shoppingCart.currentStoreView.store.website)

119

let productInTheCurrentStoreView:ProductInStoreView = currentProduct.productInStoreView > any ( pisv | pisv.storeView = self.shoppingCart.currentStoreView) in if productInTheCurrentWebsite.specialNetPrice.isDened() and productInTheCurrentStoreView.specialNetPriceFrom.isDened() and productInTheCurrentStoreView.specialNetPriceUntil.isDened() and productInTheCurrentStoreView.specialNetPriceFrom <= Now(); and productInTheCurrentStoreView.specialNetPriceUntil >= Now(); then productInTheCurrentWebsite.specialNetPrice endif [3] context ShoppingCartItem def: calculateTieredPrice (currentProduct : Product) : Money = let applicableTierPrices:Set(TierPrice) = self.shoppingCart.currentStoreView.store.website.tierPrice -> select ( tp | tp.product = currentProduct and tp.quantity <= self.quantity ) applicableTierPrices-> any ( tp | applicableTierPrices -> forAll ( tp1 | tp.quantity >= tp1.quantity ) ).oclAsType(FixedTierPrice).price [4] context ShoppingCartItem def: calculateCatalogRulesPrice (currentProduct : Product, appliedCatalogPriceRules : CatalogPriceRule) : Money = let netPrice: Money = calculateNetPrice( currentProduct ) in self.calculateCatalogRulesPriceRecursively(netPrice, appliedCatalogPriceRules) [5] context ShoppingCartItem def: calculateCatalogRulesPriceRecursively (originalPrice : Money, appliedCatalogPriceRules : CatalogPriceRule) : Money = let morePrioritaryRule: CatalogPriceRule = appliedCatalogPriceRules -> any ( r | appliedCatalogPriceRules -> forAll ( r1 | r.priority <= r1.priority) ) in let calculatedPrice:Money = if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::SetAsFixed then morePrioritaryRule.amount else if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::SubstractFixed then originalPrice - morePrioritaryRule.amount else if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::SetAsPercentage then originalPrice * morePrioritaryRule.amount else originalPrice * (1 - morePrioritaryRule.amount) endif endif endif in if appliedCatalogPriceRules -> isEmpty() then originalPrice else else self.calculateCatalogRulesPriceRecursively(calculatedPrice,appliedCatalogPriceRules > excluding(morePrioritaryRule)) endif [6] context ShoppingCartItem def: calculateOptionsIncrement (basePrice : Money) : Money = self.optionValueInOption -> collect ( ovio | if ovio.sign = Sign::Plus then if ovio.xedIncrement.isDened() then ovio.xedIncrement else basePrice * ovio.relativeIncrement endif else if ovio.xedIncrement.isDened() then -ovio.xedIncrement else - (basePrice * ovio.relativeIncrement) endif endif ) -> sum() + self.textOption -> union(self.dateOption) -> collect ( op | if op.sign = Sign::Plus then in

in

120

if op.xedIncrement.isDened() then op.xedIncrement else basePrice * op.relativeIncrement endif else if op.xedIncrement.isDened() then -op.xedIncrement else - (basePrice * op.relativeIncrement) endif endif ) -> sum() [7] context ShoppingCartItem def: calculateDiscount (discountBasis : Money, appliedShoppingCartPriceRules : ShoppingCartPriceRule) : Money = let morePrioritaryRule: ShoppingCartPriceRule = appliedShoppingCartPriceRules -> any ( r | appliedShoppingCartPriceRules -> forAll ( r1 | r.priority <= r1.priority) ) in let calculatedDiscount:Money = if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::Percentage then if morePrioritaryRule.discountQtyStep.isUndened() then discountBasis * morePrioritaryRule.amount else (discountBasis / self.quantity) * ((self.quantity / morePrioritaryRule.discountQtyStep).oor() * morePrioritaryRule.discountQtyStep) * morePrioritaryRule.amount endif else if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::Fixed then morePrioritaryRule.amount * self.quantity else if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::FixedForWholeCart then if self.shoppingCart.shoppingCartItem->excluding(self).appliedShoppingCartPriceRule-> excludes(morePrioritaryRule) then morePrioritaryRule.amount else 0.0 endif else if morePrioritaryRule.method = ShoppingCartRuleDiscountMethod::BuyXGetY then (discountBasis / self.quantity) * (self.quantity/(morePrioritaryRule.discountQtyStep + morePrioritaryRule.amount)).oor() + (self.quantity.mod((morePrioritaryRule.discountQtyStep + morePrioritaryRule.amount).oor()) morePrioritaryRule.discountQtyStep).max(0) endif endif endif in if appliedShoppingCartPriceRules -> isEmpty() then 0.0 else else calculatedDiscount + self.calculateDiscount(discountBasis, appliedShoppingCartPriceRules -> excluding(morePrioritaryRule)) endif

Derivation Rules

[1] ShoppingCartItem :: basePrice is the unitary price of the product in the website the Shopping Cart is placed, taking into account the special net price, tier prices and catalog price rules. Context ShoppingCartItem :: basePrice : Money body: self.calculateNetPrice(self.product) .min( self.calculateSpecialNetPrice( self.product )) .min( self.calculateTieredPrice(self.product)) .min( self.calculateCatalogRulesPrice( self.product, self.appliedCatalogPriceRule)) [2] ShoppingCartItem :: calculatedPrice is the unitary price of the product taking into account the base price and the custom options selected Context ShoppingCartItem :: calculatedPrice : Money body: self.basePrice + self.calculateOptionsIncrement( self.basePrice ) [3] ShoppingCartItem :: price is the price the customer pays for a unit of the product without adding taxes, shipping costs or discounts.

121

Context ShoppingCartItem :: price : Money body: if self.customPrice.isDened() then self.customPrice else self.calculatedPrice endif [4] ShoppingCartItem :: discount is the total amount able to be discounted from the set of products purchased of this shopping cart item, determined by shopping cart price rules. Context ShoppingCartItem :: discount : Money body: self.calculateDiscount( self.price * self.quantity, self.appliedShoppingCartPriceRule ) [5] ShoppingCartItem :: total is the unitary cost of this product multiplied by the quantity added to the shopping cart, minus the discount. Context ShoppingCartItem :: total : Integer body: if self.applyDiscount then self.price * self.quantity - self.discount else self.price * self.quantity endif [6] ShoppingCartItem :: appliedShoppingCartPriceRule are the shopping cart price rules that are applied to the current shopping cart item. Context ShoppingCartItem :: appliedShoppingCartPriceRule : Set(ShoppingCartPriceRule) body: let applicableRules: Set(ShoppingCartPriceRule) = ShoppingCartPriceRule.allInstances() -> select ( scr | scr.status = Status::Enabled and scr.verifyForShoppingCart(self.shoppingCart) and scr.verifyItemLevelConditionForShoppingCart(self) and scr.website -> includes( currentSession.storeView.store.website ) and scr.customerGroup -> includes( currentSession().customerGroup() ) and scr.maxUses.isDened() implies scr.timesUsed < scr.maxUses and scr.maxUsesPerCustomer.isDened() implies scr.useOfShoppingCartPriceRule -> any ( use | use.customer = self.shoppingCart.customer).timesUsed < scr.maxUsesPerCustomer and scr.inEffectFrom.isDened() implies scr.inEffectFrom <= Now() and scr.inEffectUntil.isDened() implies scr.inEffectUntil >= Now() and scr.couponCode.isDened() implies self.shoppingCart.couponCode = scr.couponCode ) in applicableRules -> select ( r | applicableRules->excluding(r) -> forAll ( r1 | r1.priority > r.priority implies r1.stopFurtherRules=false )) [7] ShoppingCartItem :: appliedCatalogPriceRule are the catalog price rules that are applied to the current shopping cart item. Context ShoppingCartItem :: appliedCatalogPriceRule : Set(CatalogPriceRule) body: let applicableRules: Set(ShoppingCartPriceRule) = CatalogPriceRule.allInstances() -> select ( scr | scr.status = Status::Enabled and scr.verifyConditionForShoppingCart(self.shoppingCart) and scr.website -> includes( currentSession().storeView.store.website ) and scr.customerGroup -> includes( currentSession().customerGroup() ) and scr.inEffectFrom.isDened() implies scr.inEffectFrom <= Now() and scr.inEffectUntil.isDened() implies scr.inEffectUntil >= Now() and ) in applicableRules -> select ( r | applicableRules->excluding(r) -> forAll ( r1 | r1.priority > r.priority implies r1.stopFurtherRules=false ))

122

Constraints

[1] Shopping cart items are identied by its product, the cart it belongs to and the eventual options choosen.

Context ShoppingCartItem :: isIdentiedByItsProductItsCartAndItsOptions() : Boolean body: let textOp: Bag(TupleType(o:TextOption,v:String)) = self.textOptionRating -> collect(t|Tuplet=t.textOption,v=t.value) in let dateOp: Bag(TupleType(o:DateOption,v:Date)) = self.dateOptionRating -> collect(t|Tuplet=t.dateOption,v=t.value) in ShoppingCartItem.allInstances() -> isUnique(Tuples=shoppingCart,p=product,t=textOp,d=dateOp,v=optionValueInOp [2] If the shopping cart item does not belong to an administration shopping cart, the custom price is undened and the discount is always applied. Context ShoppingCartItem :: denesCustomPriceAndApplyDiscountCorrectly() : Boolean body: (not self.shoppingCart.oclIsTypeOf(AdministrationShoppingCart)) implies (self.customPrice.isUndened() and self.applyDiscount) [3] The rated Text and Date Options and the selected Option Values belong to the product added in this Shopping Cart Item. Context ShoppingCartItem :: ratesOnlyOptionsOfItsProduct() : Boolean body: self.textOption -> forAll(to|to.product = self.product) and self.dateOption -> forAll(dop|dop.product = self.product) and self.optionValueInOption -> forAll(ovio|ovio.optionWithPredenedContent.product = self.product) [4] If the option is required, all Shopping Cart Items that add its related Product must give a value to it. Context Option :: isRatedWhenItIsNeeded() : Boolean body: self.isRequired implies ( if self.oclIsTypeOf(OptionWithPredenedContent) then self.product.shoppingCartItem -> forAll ( i | i.optionValueInOption -> exists (ovio|ovio.optionWithPredenedContent = self)) else if self.oclIsTypeOf(TextOption) then self.product.shoppingCartItem -> forAll ( i | i.textOption -> exists (to|to = self)) else self.product.shoppingCartItem -> forAll ( i | i.dateOption -> exists (dop|dop = self)) endif endif ) [5] If its section type is single, a Shopping Cart Item can not assign more than one value to the option. Context OptionWithPredenedContent :: isRatedWithOnlyOneValueWhenItIsNeeded() : Boolean body: self.selectionType = SelectionType::Single implies self.optionValueInOption -> forAll ( ov1, ov2 | ov1 <> ov2 implies ov1.shoppingCartItem <> ov2.shoppingCartItem ) [6] All products in the shopping cart should be enabled, in stock and available in the current website. Context ShoppingCartItem :: hasOnlyAProductAbleToBeBougth() : Boolean body: self.product.productInStoreView -> any ( piw |

123

piw.storeView = self.shoppingCart.currentStoreView ).status = Status::Enabled and self.product.productInWebsite -> any ( piw | piw.website = self.shoppingCart.currentStoreView.store.website ).isAvailable and self.product.stockStatus = #InStock

Description
A Shopping Cart Item has the following attributes: quantity: the number of items puchased of this product. giftMessage: a message that will be delivered to the person that receives the products added in this Shopping Cart Item. basePrice: the unitary price of the product in the website the Shopping Cart is placed, taking into account the special net price, tier prices and catalog price rules. Derived Attribute. calculatedPrice: the unitary price of the product taking into account the base price and the custom options selected. Derived Attribute. customPrice: a different price that can be optionally applied for this Shopping Cart Item, instead of applying the products price. price: the unitary price of the product taking into account the calculated price and the custom price. No taxes, discounts or shipping costs are added yet. Derived Attribute. discount: the global amount able to be discounted from the set of products added in this Shopping Cart Item, determined by shopping cart price rules. Derived Attribute. applyDiscount: determines if discount dened above will be applied or not. total: the total cost of this Shopping Cart Item. Derived Attribute. If the product purchased in this Shopping Cart Item has options, its values are specied in the item itself: text and date options are rated, while an option value is choosen for Options With Predened Content. Thus, Products with different Options conguration are added to the Shopping Cart as different Shopping Cart Items.

124

2.8.3
I

Shopping cart items of non-simple products

Overview
Shopping Cart Items of Downloadable, Congurated or Bundle Products need to save additional information.

Schema Diagram

Derivation Rules
125

[1] SCItemOfADownloadableProduct :: calculatedPrice is the unitary price of the product taking into account the base price, the custom options selected and increments due to the purchased Downloadable Items. Context SCItemOfADownloadableProduct :: calculatedPrice : Money body: if self.downloadableProduct.purchaseItemsSeparatelly = Status::Enabled then self.basePrice + self.calculateOptionsIncrement( self.basePrice ) else self.downloadableItem -> collect ( dw | if dw.sign = Sign::Plus then if dw.xedIncrement.isDened() then dw.xedIncrement else self.basePrice * dw.relativeIncrement endif else if dw.xedIncrement.isDened() then -dw.xedIncrement else - (self.basePrice * dw.relativeIncrement) endif endif ) -> sum() + self.basePrice + self.calculateOptionsIncrement( self.basePrice ) endif [2] SCItemOfAConguratedProduct :: basePrice the base price of the congurable product (not the congurated). Context SCItemOfAConguratedProduct :: basePrice : Money body: self.calculateNetPrice( self.congurableProduct ) .min( self.calculateSpecialNetPrice( self.congurableProduct ) ) .min( self.calculateTieredPrice( self.congurableProduct ) ) .min( self.calculateCatalogRulesPrice( self.congurableProduct, self.catalogPriceRuleOfCongurableProduct ) ) [3] SCItemOfAConguratedProduct :: calculatedPrice the unitary price of the product taking into account the base price, the custom options selected and the increments due to the Conguration chosen. Context SCItemOfAConguratedProduct :: calculatedPrice : Money body: self.conguratedProduct.congurationOfACongurableProduct -> collect ( cpa | if cpa.sign = Sign::Plus then if cpa.xedIncrement.isDened() then cpa.xedIncrement else self.calculateBasePrice() * cpa.relativeIncrement endif else if cpa.xedIncrement.isDened() then -cpa.xedIncrement else - (self.calculateBasePrice() * cpa.relativeIncrement) endif endif ) -> sum() + self.calculateBasePrice() + self.calculateOptionsIncrement( self.basePrice ) [4] PurchaseOfABundleProductOption :: basePriceOfBundleProductOption is the base price, in the current website, of the product purchased as a bundle option (as it was purchased alone). Context PurchaseOfABundleProductOption :: basePriceOfBundleProductOption : Money body: self.calculateNetPrice( self.bundleProductOption.product ) -> min( self.calculateSpecialNetPrice( self.bundleProductOption.product ) ) -> min( self.calculateTieredPrice( self.bundleProductOption.product, self.quantity ) ) -> min( self.calculateCatalogRulesPrice( self.bundleProductOption.product, self.catalogPriceRuleOfBundleProduct ) ) [5] SCItemOfABundleProduct :: bundlePrice is the unitary price of the product taking into account the products purchased as Bundle Options and, if present, the custom options selected, in the current website Context SCItemOfABundleProduct :: bundlePrice : Money body: if self.bundleProduct.priceMethod = PriceMethod::Dynamic then

126

self.purchaseOfABundleProductOption -> collect ( p | p.quantity * p.basePriceOfBundleProductOption ) -> sum() else self.purchaseOfABundleProductOption -> collect ( pbpo | pbpo.quantity * ( if pbpo.bundleProductOption.sign = Sign::Plus then if pbpo.bundleProductOption.xedIncrement.isDened() then pbpo.bundleProductOption.xedIncrement else self.calculateNetPrice(self.bundleProduct) * pbpo.bundleProductOption.relativeIncrement endif else if pbpo.bundleProductOption.xedIncrement.isDened() then -pbpo.bundleProductOption.xedIncrement else - (self.calculateNetPrice(self.bundleProduct) * pbpo.bundleProductOption.relativeIncrement) endif endif ) ) -> sum() + self.calculateNetPrice( self.bundleProduct ) + self.calculateOptionsIncrement( calculateNetPrice(self.bundleProduct) ) endif [6] SCItemOfABundleProduct :: calculatedPrice is the unitary price of the product taking into account the bundle price and the reductions due to special and tiered prices. Context SCItemOfABundleProduct :: calculatedPrice : Money body: let specialBundlePrice: Real = let bundleProductInTheCurrentWebsite:BundleProductInWebsite = self.bundleProduct.bundleProductInWebsite -> any ( piw | piw.websiteWhereIsSpeciedAsBundleProduct = self.shoppingCart.currentStoreView.store.website) in let productInTheCurrentStoreView:ProductInStoreView = self.bundleProduct.productInStoreView -> any ( pisv | pisv.storeView = self.shoppingCart.currentStoreView) in if bundleProductInTheCurrentWebsite.specialNetPriceReduction.isDened() and productInTheCurrentStoreView.specialNetPriceFrom.isDened() and productInTheCurrentStoreView.specialNetPriceUntil.isDened() and productInTheCurrentStoreView.specialNetPriceFrom <= Now() and productInTheCurrentStoreView.specialNetPriceUntil >= Now() then bundlePrice * bundleProductInTheCurrentWebsite.specialNetPriceReduction else bundlePrice endif in let applicableTierPrices:Set(TierPrice) = self.shoppingCart.currentStoreView.store.website.tierPrice -> select ( tp | tp.product = currentProduct and tp.quantity <= quantity) in let tieredBundlePrice: Money = bundlePrice * applicableTierPrices-> select ( tp | applicableTierPrices -> forAll ( tp1 | tp.quantity >= tp1.quantity ) ).percentage in bundlePrice.min( specialBundlePrice ).min( tieredBundlePrice ) .min( self.calculateCatalogRulesPrice( self.bundleProductOption.product, self.catalogPriceRuleOfBundleProduct ) )

Constraints

[1] The downloadable items of the order line are downloadable items of the purchased downloadable product. Context SCItemOfADownloadableProduct :: hasTheCorrectDownloadItems() : Boolean body: self.downloadableProduct.downloadableItem -> includesAll( self.downloadableItem ) [2] If the downloadable product does not allow to puchase its items separatelly, all downloadable items are purchased. Context SCItemOfADownloadableProduct :: hasAllDownloadItemsWhenNeeded() : Boolean

127

body: self.downloadableProduct.purchaseItemsSeparatelly = Status::Enabled implies self.downloadableItem -> includesAll( self.downloadableProduct.downloadableItem ) [3] A purchase of a downloadable item has not been downloaded more times than the maximum allowed by the downloadable item conguration and the website conguration. Context PurchaseOfADownloadableItem :: hasNotMadeMoreDownloadsThanPermitted() : Boolean body: let maximumDownloadCountOfWebsite: PositiveInteger = self.SCItemOfADownloadableProduct.order.storeView.store.website.catalogCongurationInWebsite.maximumDownloadCount in self.downloadableItem.maximumDownloadCount.isDened() implies self.downloadCount <= self.downloadableItem.maximumDownloadCount and maximumDownloadCountOfWebsite.isDened() implies self.downloadCount <= maximumDownloadCountOfWebsite [4] A Shopping Cart Item is not directly associated to a congurable or grouped product.

Context ShoppingCartItem :: doesNotPurchaseCongurableBundleOrGroupedProductsDirectly() : Boolean body: not ( self.product -> oclIsTypeOf(CongurableProduct) or self.product -> oclIsTypeOf(GroupedProduct) or self.product -> oclIsTypeOf(BundleProduct) ) [5] The congurated product purchased is one of the associated products of the congurable product it has been purchaset through. Context SCItemOfAConguratedProduct :: hasACorrectCongurableProduct() : Boolean body: self.congurableProduct.associatedProduct -> includes( self.conguratedProduct ) [6] The bundle product options chosen are options available of the purchased bundle product.

Context SCItemOfABundleProduct :: hasTheCorrectBundleProductOptions() : Boolean body: self.bundleProduct.bundleProductItem.bundleProductOption -> includesAll( self.bundleProductOption )

Description

A Shopping Cart Item Of a Downloadable Product must specify which downloadable items have been purchased. The selected items will affect its base price. For each item, the system saves: downloadCount: the number of times the item has been downloaded. calculatedPrice: an amount which includes not only the custom option price increments, but also the increments due to the purchased Downloadable Items. Shopping Cart Items of a Congurated Product must know the information about: congurableProduct: the Congurable Product this product has been bought through. catalogPriceRuleOfCongurableProduct: the catalog price rules applied to the congurable product (not the congurated). basePrice: the base price of the congurable product (not the congurated). calculatedPrice: an amount which includes not only the custom option price increments, but also the increments due to the Conguration chosen.

128

The base price of a Shopping Cart Item Of a Congurated Product will be calculated taking into account the base price of the Congurable Product and the increments dened in the corresponding Conguration of the Congurable Product. An Shopping Cart Item Of a Bundle Product must specify: bundlePrice: an amount taking into account the price method of the Bundle Product and the increments due to the products purchased as Bundle Options. calculatedPrice: an amount which includes not only the bundle price, but also the reductions due to special reductions, relative tiered prices and catalog price rules. For each bundle product option, the following attributes must be also specied: quantity: the purchased quantity of this product. basePriceOfBundleProductOption: the base price of the product associated to the selected bundle product option. The bundle price of an Shopping Cart Item Of a Bundle Product will be calculated depending on the price method dened by the Bundle Product. Finally, the base price of the Shopping Cart Item will be calculated by applying to the Bundle Net Price the reductions due to specialNetPrice, tieredPrice and Catalog Price Rules. I

Price calculation process


The price calculation process can be informally represented by the following schema.

129

130

2.8.4
I

Orders

Overview
Orders are the conrmation that a customer wants to buy the contents of its shopping cart.

Schema Diagram

131

Derivation Rules
[1] Order :: purchased is the Date and Time when the order was placed

Context Order :: purchased : DateTime body: Now() [2] Order :: shippingCosts are the costs derived from the used shipping method.

Context Order :: shippingCosts : Money body: self.shippingMethod.shippingMethodInWebsite -> select ( smiw | smiw.website = self.storeView.store.website).calculateCost( self.orderLine, self.delivery ) [3] Order :: total its the total cost the user will pay for the products ordered, including its shipping costs. Context Order :: total : Money body: self.orderLine.total -> sum() + self.shippingCosts [4] Order :: name is the rst and last name of the orders customer.

Context Order :: name : String body: self.customer.rstName.concat( self.customer.lastName ) [5] Order :: eMail is the email of the orders customer.

Context Order :: eMail : String body: self.customer.eMail [6] Order :: websiteName its the name of the website where the order has been placed.

Context Order :: websiteName : Money body: self.storeView.store.website.name [7] Order :: storeName its the name of the store where the order has been placed.

Context Order :: storeName : Money body: self.storeView.store.name [8] Order :: storeViewName its the name of the store view where the order has been placed.

Context Order :: storeViewName : Money body: self.storeView.name

Constraints
[1] An order is identied by the customer that has place it, the store view where it has been made and the time it was created. Context Order :: isIdentiedByItsCustomerStoreViewAndCreationDate() : Boolean body: Order.allInstances() -> isUnique(Setcustomer,storeView,purchased) [2] The products that appear in the order should be available in the website the store of the order belongs to.

132

Context Order :: hasProductsFromTheCorrectStore() : Boolean body: self.storeView.store.website.product.sku -> includesAll(self.orderLine.productSku -> asSet()) [3] An order with only virtual and downloadable products should not have shipping method and address dened, an order with any other type of product should. Context Order :: hasShippingPropertiesOnlyWhenNeeded() : Boolean body: let products : Set(Product) = Product.allInstances() -> select(p|self.orderLine.productSku -> includes(p.sku)) in products -> forAll ( p | (p.oclIsTypeOf(VirtualProduct) or p.oclIsTypeOf(DownloadableProduct) )= (self.delivery -> isEmpty() and self.shippingMethod -> isEmpty()) ) . [4] If an Order has been edited, so it has a newer version of itself, the older version should be cancelled. Context Order :: statusIsCancelledIfWasEdited() : Boolean body: self.newVersion -> notEmpty() implies self.status = OrderStatus::Cancelled. [5] If an Order is Pending, no invoices or shipments are made for it.

Context Order :: meetsPendingStatusConditions() : Boolean body: self.status = OrderStatus::Pending implies ( self.invoice -> isEmpty() and self.shipment -> isEmpty() ) [6] If an Order is Processing, some invoices are made for it, but not all possible.

Context Order :: meetsProcessingStatusConditions() : Boolean body: self.status = OrderStatus::Processing implies ( self.invoice -> notEmpty() and self.invoice.invoiceLine.quantity -> sum() < self.orderLine.quantity -> sum() and self.shipment -> notEmpty() and self.shipment.shipmentLine.quantity -> sum() < self.orderLine.quantity -> sum() ) [7] If an Order is Complete, all possible invoices and shipments are made for it, but not all credit memos.. Context Order :: meetsCompleteStatusConditions() : Boolean body: self.status = OrderStatus::Complete implies ( self.invoice.invoiceLine.quantity -> sum() = self.orderLine.quantity -> sum() and self.shipment.shipmentLine.quantity -> sum() = self.orderLine.quantity -> sum() and self.refund.refundLine.quantity -> sum() < self.orderLine.quantity -> sum() ) [8] If an Order is Closed, credit memos cover all items ordered, which implies Invoices cover all items also because of hasNotMoreRefundedProductsThanInvoiced constraint. Context Order :: meetsClosedStatusConditions() : Boolean body: self.status = OrderStatus::Closed implies ( self.refund.refundLine.quantity -> sum() = self.orderLine.quantity -> sum() ) [9] If an Order is Cancelled, not all invoices and shipments can be already made for it.

133

Context Order :: meetsCancelledAndHoldStatusConditions() : Boolean body: (self.status = OrderStatus::Cancelled or self.status = OrderStatus::Hold) implies ( self.invoice.invoiceLine.quantity -> sum() < self.orderLine.quantity -> sum() and self.shipment.shipmentLine.quantity -> sum() < self.orderLine.quantity -> sum() )

Description
When a Customer conrms that he wants to buy the contents of a Shopping Cart, the system generates an Order. Orders have the following information: name: the name of the customer who has placed the order. Derived Attribute. eMail: the orders customer eMail. Several notications concerning this Order will be sent here. Derived Attribute. websiteName: the name of the website where the order has been placed. Derived Attribute. storeName: the name of the store where the order has been placed. Derived Attribute. storeViewName: the name of the store view where the order has been placed. Derived Attribute. purchased: the time the Order was placed. couponCode: a literal code that can enable the application of a Shopping Cart Price Rule that matches it. eMailSent: indicates if an email has been sent to the orders costumer to notice him the invoice was recorded. giftMessage: a message that will be delivered to the person that receives the products purchased in this order. shippingCosts: the amount that will be paid for shipping the purchased products to the customers delivery address, using the selected shipping method. total: the total amount the customer will pay for this order. Derived Attribute. The total invoiced, non reinvoiceable, paid, shipped and refunded amounts will be detailled in the following sections. An Order has also a status attribute, that can take the following values: Pending: no invoices or shipments have been made for this Order. Processing: some invoices or shipments have been made for this Order, but they do not cover all its ordered products. Completed: the whole Order has been paid and shipped, but not all items had been refunded. Closed: the whole Order has been refunded (so, it had been already paid before). Cancelled: the Order has been cancelled., so all the items that had not been invoiced and/or shipped before are cancelled. Items already invoiced and/or shipped are not affected. A completed or closed Order cannot be Cancelled. Hold: the Order is temporary holded, so no changes can be made to it until someone unholds it. Each different Product purchased in this Order is represented as an OrderLine. Order lines will be detailed in the next section. The entity type Order participates in several relationship types: 134

storeView: the storeView the costumer used to record this Order. If the order was created by and administrator, he should choose one store view. The website that store view belongs to determines to which product list you will have access when creating the order and to which of the customers Buying Process Information lists you will have access. customer: the Customer that has made the Order. If the customer does not have an account in the website store you have chosen is in, an account will be created for the customer in that website upon completion of the order, with all the customer information duplicated. A Guest (a not registered Costumer) can also make orders without registrating themselves. In this case, no Customer will be associated to the Order. customerGroup: some characteristics (as taxes) will be applied to the Order depending on which CustomerGroup it is related. Even if normally this will be the same as the group the Customer belongs to, administrators can choose another from the backend. Even thought, the group the costumer belongs to is not changed. billing: the adress where the bill for this Order will be sent. It is not mandatory that they should be part of the Customer adresses. delivery: the adress where the products purchased will be shipped. It is not mandatory that they should be part of the Customer adresses. rateApplicationAdress: will be used to calculate the tax rates applied to this order. shippingMethod: the method that will be used to ship the products to the Customers delivery adress. Each method involves a specic method for calculating the costs. paymentMethod: the method that will be used for the Costumer to pay the order amount. If it is a credit card method, the credit card info is saved. newVersion / previousVersion: already recorded Orders can be edited. This will simultaneously create a new order and cancel the previous order. Each version of an other is associated to its immediately newer and previous version. Concerning currency management, an Order has the following information: genericBaseCurrency: the currency setted as the generic base currency when the order was placed. websiteRedenedBaseCurrency: the currency setted as websites base currency when the order was placed, if dened. The conversion rate with respect to the generic base currency at the time the order was placed is saved. purchasingCurrency: the currency in which the order was placed. If the order was placed using the genericBaseCurrency, no purchasing currency is saved. The conversion rate with respect to the generic base currency at the time the order was placed is saved. Several Comments can be made to an Order, even when it is already created. For each Comment, the system saves its text, the time it was created, an status and if the customer who purchases the order had been notied for this comment. I

State Transition Diagram


The state of Orders can be conceptually modeled by using a state transition diagram.

135

136

2.8.5
I

OrderLines

Overview
Each different Product purchased in a Order is represented by an OrderLine.

Schema Diagram

Constraints
[1] An order line is identied by its order, the product sku and the info about the options choosen.

Context OrderLine :: isIdentiedByItsOrderProductSkuAndOptions() : Boolean body: OrderLine.allInstances() -> isUnique(Setorder,productSku,textOptions,dateOptions,predenedContentOptions)

Description
An OrderLine has the following attributes: productSku: the sku of the purchased product. productName: the name of the purchased product. quantity: the number of items puchased of this product. 137

giftMessage: a message that will be delivered to the person that receives the products purchased in this order line. price: the unitary price the customer has nally paid for the product, taking into account the calculated price and the custom price. No taxes, discounts or shipping costs are compounded. tax: the global cost from the application of all the applicable tax rates to the set of products purchased in this order line. discount: the global amount that was discounted from the set of products purchased in this order line, determined at the purchasing time by shopping cart price rules. total: the total cost of this order line. If the product purchased in this order line has options, the values that the customer has given for them are specied in the order line.

138

2.8.6
I

Invoices

Overview
Magento allows administrators to generate invoices for the ordered products.

Schema Diagram

Derivation Rules
[1] Invoice :: shippingCosts is the shipping amount for the entire order, if it is the rst Invoice for its Order; zero otherwise. Context Invoice :: shippingCosts : Integer body: let isFirstInvoice:Boolean = equals(self, self.order.invoice -> any ( i | self.order.invoice -> forAll ( i2 | i <> i2 implies i.createdAt < i2.createdAt ) ) ) in if isFirstInvoice then self.order.shippingCosts else 0 endif [2] Invoice :: total its the total cost the user have paid, including shipping costs and taxes.

139

Context Invoice :: total : Integer body: self.invoiceLine.total -> sum() + self.shippingCosts [3] InvoiceLine :: total is the unitary cost paid for this product multiplied by the quantity in the Invoice. Context InvoiceLine :: total : Integer body: self.orderLine.price * self.quantity + (self.orderLine.tax / self.orderLine.quantity) * self.quantity + (self.orderLine.discount / self.orderLine.quantity) * self.quantity [4] Order :: notCancelledInvoice is the set of invoices made for this Order that had not been cancelled. Context Order :: notCancelledInvoice : Set(Invoice) body: self.invoice -> select ( i | i.status <> InvoiceStatus::Cancelled ) [5] Order :: totalInvoiced its the total amount already invoiced for the products of this order.

Context Order :: totalInvoiced : Money body: self.notCancelledInvoice.total -> sum() [6] Order :: totalPaid its the total amount that the Costumer has already paid for the products of this order. Context Order :: totalPaid : Money body: self.invoice -> select ( i | i.status = InvoiceStatus::Paid ).total -> sum() [7] Order :: totalNonReInvoiceable its the total amount of the cancelled orders that where already paid online througth a third-party gateway, so its products are not able to be re-invoiced again. Context Order :: totalNonReInvoiceable : Money body: self.invoice -> select ( i | i.status = InvoiceStatus::Cancelled and i.isPaidOnline).total -> sum()

Constraints
[1] An invoice line is identied by its invoice and order line.

Context InvoiceLine :: isIdentiedByItsInvoiceAndOrderLine() : Boolean body: InvoiceLine.allInstances() -> isUnique(Setinvoice,orderLine) [2] An invoice line refers to an order line of the corresponding order.

Context InvoiceLine :: refersToACorrectOrderLine() : Boolean body: self.invoice.order.orderLine -> includes(self.orderLine) [3] An invoice is identied by the order it belongs to and the time it was created.

Context Invoice :: isIdentiedByItsOrderAndCreationDate() : Boolean body: Invoice.allInstances() -> isUnique(Setorder,createdAt) [4] The payment method of an invoice that has been paid automatically online should be one of the followings: Authorize.net, PayFlowPro, PayPal or GoogleCheckout. Context Invoice :: isPaidOnlineOnlyIfHasExternalPaymentMethod() : Boolean body:

140

self.isPaidOnline implies ( self.order.paymentMethod.oclIsTypeOf( AuthorizeNet ) or self.order.paymentMethod.oclIsTypeOf( PayFlowPro ) or self.order.paymentMethod.oclIsTypeOf( PayPalMethod ) or self.order.paymentMethod.oclIsTypeOf( GoogleCheckout ) ) [5] Invoices related to this order dont have a greater quantity of a product than the quantity ordered for this product. Context OrderLine :: hasNotMorePaidProductsThanOrdered() : Boolean body: let notCancelledLines: Set(InvoiceLine) = self.invoiceLine -> select(li|li.invoice.status <> InvoiceStatus::Cancelled ) in notCancelledLines.quantity -> sum() <= self.quantity

Description
An Invoice is a document issued by the seller to the customer listing the goods or services purchased and the sum of money due. Multiple Invoices can be created per Order, containing as much of the purchased item quantity. However, each unit of each item can only be invoiced one time. In Magento, the Invoice for a product should be created at the latest when the customer pays the money for this product, but they can also be created before. The system saves the following information for each Invoice: createdAt: the time the Invoice has been recorded. emailSent: indicates if an email has been sent, during the creation of the Invoice, to the orders costumer, to notice him the Invoice was recorded. capturingMethod: indicates the method used to capture the payment for this invoice: automathically online with Magento, automatically Online throught a third party method or only registering the invoice (with no payment). isPaidOnline: indicates if the customers payment of the Invoices amount has been done automatically during Invoice creation. This can only be done throught an external online payment method: Authorize.net, PayFlowPro, PayPal or GoogleCheckout. shippingCosts: the shipping costs. They are only compounded for the rst Invoice made for an Order, regardless of how many products are included in this rst Invoice.Derived Attribute. total: the total price the Costumer have should pay for this Invoice. The status of an Invoice indicates whether: Pending: the Invoices amount has not been paid yet by the customer. Paid: the Invoices amount has been already paid. Cancelled: the administrator has made an error creating the invoice or has changed his opinion, and does not want to take this invoice into account no more. Cancelled Invoices can be re-invoiced or not depending on if the invoice has been automatically paid online or not. In the last, the products that where in the invoice can be re-invoiced, whether in the rst they can not. Each InvoiceLine records that one kind of product has been paid in this Invoice. The product is specied by the related Order Line. The following information is also saved:

141

quantity: records the number of items of this Product that had been paid. total: is the total amount paid for this quantity of this product. Derived Attribute. Several Comments can also be made to a Invoice, even when it is already created. Of course, each Invoice is also related to the Order it belongs to. I

State Transition Diagram


The state of Invoices can be conceptually modeled by using a state transition diagram.

142

2.8.7
I

Shipments

Overview
Magento records the items in an Order which have been already shipped to the Costumers destination.

Schema Diagram

Constraints
[1] A shipment is identied by the order it belongs to and the time it was created.

Context Shipment :: isIdentiedByItsOrderAndCreationDate() : Boolean body: Shipment.allInstances() -> isUnique(Setorder,createdAt) [2] A refund line refers to an order line of the corresponding order.

Context ShipmentLine :: refersToACorrectOrderLine() : Boolean body: self.shipment.order.orderLine -> includes(self.orderLine) [3] Shipments related to this order do not ship a greater quantity of a product than the quantity ordered for this product. Context OrderLine :: hasNotMoreShippedProductsThanOrdered() : Boolean body: self.shipmentLine.quantity -> sum() <= self.quantity

143

Description
A Shipment its a record that some quantity of the products in that Order have been already shipped to its buyer, and they were not recorded to be shipped before. Whether their physically shipment could be together or not, the fact that they appear in the same Shipment means that someone (normally a system administrator) has recorded their shipment together, at a determinated point of time. Multiple shipments can be created per Order, as someone has recorded at diferent moments that this products have been shipped. However, each unit of each item can only be shipped only one time, so there is a nite limit of Shipments. The system saves the following information for each shipment: createdAt: the time the Shipment has been recorded. emailSent: indicates if an email has been sent to the orders costumer to notice him the shipment was recorded. trackingNumber: can optionally be associated to the shipment in order to facilitate eventual location purposes. Each ShipmentLine records that one kind of product has been shipped in this shipment.The product is specied by the related Order Line. The following information is also saved: quantity: records the number of items of this Product that had been shipped. Several Comments can also be made to a Shipment, even when it is already created. Of course, each shipment is related to the Order it belongs to.

144

2.8.8
I

Refund

Overview
Magento records the Refunds made by Customers. Magento refers them as "Credit Memos", which is the document that registers a Refund.

Schema Diagram

Derivation Rules
[1] Refund :: total is the total amount refunded to the costumer, including the shipping and the additional amounts refunded (which are added) and the fee (which is substracted). Context Refund :: total : Integer body: self.refundLine.total -> sum() + self.shippingAmount + self.additionalAmount - self.fee [2] RefundLine :: total is the unitary cost of this product multiplied by the quantity of items refunded of this product. Context RefundLine :: total : Boolean body: self.orderLine.price * self.quantity [3] Order :: totalRefunded its the total amount of this order that has been refunded to the costumer.

145

Context Order :: totalRefunded : Integer body: self.refund.total -> sum()

Constraints
[1] A refund is identied by the order it belongs to and the time it was created.

Context Refund :: isIdentiedByItsOrderAndCreationDate() : Boolean body: Refund.allInstances() -> isUnique(Setorder,createdAt) [2] A refund line refers to an order line of the corresponding order.

Context RefundLine :: refersToACorrectOrderLine() : Boolean body: self.refund.order.orderLine -> includes(self.orderLine) [3] A refund line refers to an order line that has been already invoiced.

Context RefundLine :: refersToAnOrderLineAlreadyInvoiced() : Boolean body: self.orderline.invoiceLine -> notEmpty() [4] The total quantity refunded for each product should be equal or smaller than the total quantity invoiced. Context OrderLine :: hasNotMoreRefundedProductsThanInvoiced() : Boolean body: let notCancelledLines: Set(InvoiceLine) = self.invoiceLine -> select(li|li.invoice.status <> InvoiceStatus::Cancelled ) in notCancelledLines.quantity -> sum() <= self.refundLines.quantity -> sum() [5] The total quantity refunded for this order cannot be greater than the total quantity paid.

Context Order :: hasNotRefundedMoreThanPaid() : Boolean body: self.totalRefunded <= self.totalPaid [6] The total amount refounded from the shipping cost of an order in all its refunds cannot be greater than the shipping costs Context Order :: hasRefundsWithCorrectRefundShipping() : Boolean body: self.refund.shippingAmount -> sum() <= self.shippingCosts [7] We cannot create a Refund for an Order until an Invoice has been created for this Order.

Context Order :: hasARefundOnlyIfHasInvoice() : Boolean body: self.refund -> notEmpty() implies self.invoice -> notEmpty()

Description
A Refund is placed when a Customer returns a purchased Product that is unsatisfactory for him. This will normally cause the seller to give back the amount paid for this product, althought the returned quantity can be increased or decreased. The status of the refund indicates whether: Pending: the customer has returned the product, but no amount money is given back to him. Refunded: the customer has returned the product and the seller has given back him the corresponding amount. 146

Cancelled: the customer has nally changed his opinion an does not want to refund the product no more. Refunds could not be deleted from the system. A product can not be refunded until it is paid. Multiple Refunds can be created per Order, but each unit can only be refunded one time. The system saves the following information for each refund: createdAt: the time the Shipment has been recorded. emailSent: indicates if an email has been sent, during the creation of the refund, to the orders costumer, to notice him the refund was recorded. shippingAmount: the amount refunded from the shipping costs. additionalAmount: an additional refund, not related to any particular aspect of the order. . fee: an amount charged to the customer for placing the refund. It is subtracted from the total refunded. total: the total amount that will be refunded to the Costumer for this Refund. Derived Attribute. Each RefundLine records that one type of product has been refunded. The product is specied by the related Order Line. The following information is also saved: quantity: records the number of items of this Product that had been refunded. total: is the total amount refunded for the quantity of that product in this Refund, as it is described in its derivation rule. Derived Attribute. Several Comments can also be made to a Refund, even when it is already created. Of course, each Refund is related to the Order it belongs to. I

State Transition Diagram


The state of Refunds can be conceptually modeled by using a state transition diagram.

147

Behavioral Schema. Use Case Specication


In this chapter we develop the rst part of the behavioral schema of the Magento information system. Section 3.1 denes the scope of the schema elicitation, while section 3.2 describes the way the schema is presented. Section 3.3 presents an overview of the described Use Cases, which are detailed in the remaining sections.

3.1 Scope
Use Cases specication covers all the functions that the system perform within the scope dened in section 2.1.

3.2 Schema presentation


The main purpose of a behavioral schema is to specify the valid changes in the domain state, as well as the actions that the described system can perform. In the following sections of this chapter, and in the next chapter, we describe Magentos behavioral schema. We show rst a list of all the dened use cases and its primary actor, in order to give an overview of the most important funcionalities of the system and the stakeholders that interact with them. This list can be easily represented by a use case diagram. After that, each use case is specied textually, giving the following information:
I

Primary Actor(s) Precondition Trigger Main Success Scenario Extensions

The Main Success Scenario and Extensions are described as an interaction of activities between the primary actors and the system. Some of those activities are mapped to system Events, using the following syntaxis: 148

[-> EventName] Use Cases are organised in six groups. First ve are the same as in Structural Schema. They are dened in section 2.3. In addition, Magentos behavioral schema includes several use cases that retrieve information about the system, without modifying its state. They are specied here and classied in the Store Reports Use Case group.

3.3 Use Case Overview


I

Store Conguration
1. Add a website. Primary Actor: Store Administrator. 2. Edit a website. Primary Actor: Store Administrator. 3. Delete a website. Primary Actor: Store Administrator. 4. Select the default website. Primary Actor: Store Administrator. 5. Add a store. Primary Actor: Store Administrator. 6. Edit a store. Primary Actor: Store Administrator. 7. Delete a store. Primary Actor: Store Administrator. 8. Select the default store of a website. Primary Actor: Store Administrator. 9. Add an store view. Primary Actor: Store Administrator. 10. Edit an store view. Primary Actor: Store Administrator. 11. Delete an store view. Primary Actor: Store Administrator. 12. Select the default store view of a store. Primary Actor: Store Administrator. 13. Select the default language. Primary Actor: Store Administrator. 14. Change the catalog conguration values. Primary Actor: Store Administrator. 15. Change the stock conguration values. Primary Actor: Store Administrator. 16. Change the wishlist conguration values. Primary Actor: Store Administrator. 17. Change the sales conguration values. Primary Actor: Store Administrator. 18. Change the customer conguration values. Primary Actor: Store Administrator. 19. Change the tax conguration values. Primary Actor: Store Administrator. 20. Change the shipping conguration values. Primary Actor: Store Administrator. 21. Change the tell to a friend conguration values. Primary Actor: Store Administrator. 22. Change the currency conguration values. Primary Actor: Store Administrator. 23. Change the enabled currencies. Primary Actor: Store Administrator. 24. Update currency rates. Primary Actor: Store Administrator. 25. Change the geographical conguration values. Primary Actor: Store Administrator. 26. Change shipping method values. Primary Actor: System Administrator. 27. Change payment method values. Primary Actor: System Administrator. 28. Add a customer tax class. Primary Actor: Store Administrator. 29. Edit a customer tax class. Primary Actor: Store Administrator. 30. Delete a customer tax class. Primary Actor: Store Administrator. 149

31. Add a product tax class. Primary Actor: Store Administrator. 32. Edit a product tax class. Primary Actor: Store Administrator. 33. Delete a product tax class. Primary Actor: Store Administrator. 34. Add a tax rate. Primary Actor: Store Administrator. 35. Edit a tax rate. Primary Actor: Store Administrator. 36. Delete a tax rate . Primary Actor: Store Administrator. 37. Add a tax rule. Primary Actor: Store Administrator. 38. Edit a tax rule. Primary Actor: Store Administrator. 39. Delete a tax rule . Primary Actor: Store Administrator.

Customers
1. Create a Customer. Primary Actor: Customer, Store Administrator. 2. Change password. Primary Actor: Customer. 3. Change customer details. Primary Actor: Customer. 4. Administrate address book. Primary Actor: Customer. 5. Edit a customer. Primary Actor: Store Administrator. 6. Delete a customer. Primary Actor: Store Administrator. 7. Show account information. Primary Actor: Customer. 8. Show address book. Primary Actor: Customer. 9. Add a customer group. Primary Actor: Store Administrator. 10. Edit a customer group. Primary Actor: Store Administrator. 11. Delete a customer group. Primary Actor: Store Administrator. 12. Add an administrator. Primary Actor: Store Administrator. 13. Edit an administrator. Primary Actor: Store Administrator. 14. Delete an administrator. Primary Actor: Store Administrator. 15. Add a role. Primary Actor: Store Administrator. 16. Edit a role. Primary Actor: Store Administrator. 17. Delete a role. Primary Actor: Store Administrator. 18. Log In. Primary Actor: Customer. 19. Log Out. Primary Actor: Customer. 20. Open session. Primary Actor: Customer. 21. Finish session. Primary Actor: Customer. 22. Change the current Website. Primary Actor: Customer. 23. Change the current Store. Primary Actor: Customer. 24. Change the current Store View. Primary Actor: Customer. 25. Change the current Currency. Primary Actor: Customer.

Store Administration
1. Add a product. Primary Actor: Store Administrator. 150

2. Edit a product. Primary Actor: Store Administrator. 3. Delete a product. Primary Actor: Store Administrator. 4. Add a product category. Primary Actor: Store Administrator. 5. Edit a product category. Primary Actor: Store Administrator. 6. Move a product category. Primary Actor: Store Administrator. 7. Delete a product category. Primary Actor: Store Administrator. 8. Add an attribute. Primary Actor: Store Administrator. 9. Edit an attribute. Primary Actor: Store Administrator. 10. Delete an attribute. Primary Actor: Store Administrator. 11. Add an attribute set. Primary Actor: Store Administrator. 12. Edit an attribute set. Primary Actor: Store Administrator. 13. Delete an attribute set. Primary Actor: Store Administrator. 14. Administrate tier prices of a product. Primary Actor: Store Administrator. 15. Add a catalog price rule. Primary Actor: Store Administrator. 16. Edit a catalog price rule. Primary Actor: Store Administrator. 17. Delete a catalog price rule. Primary Actor: Store Administrator. 18. Add a shopping cart price rule. Primary Actor: Store Administrator. 19. Edit a shopping cart price rule. Primary Actor: Store Administrator. 20. Delete a shopping cart price rule. Primary Actor: Store Administrator.

Additional Activities
1. Tag a product. Primary Actor: Customer. 2. Add a tag. Primary Actor: Store Administrator. 3. Edit a tag. Primary Actor: Store Administrator. 4. Delete a tag. Primary Actor: Store Administrator. 5. Show tags of a customer. Primary Actor: Customer. 6. Show most popular tags. Primary Actor: Customer. 7. Show all tags. Primary Actor: Customer. 8. Add a review. Primary Actor: Customer, Store Administrator. 9. Edit a review. Primary Actor: Store Administrator. 10. Delete a review. Primary Actor: Store Administrator. 11. Add a review property. Primary Actor: Store Administrator. 12. Edit a review property. Primary Actor: Store Administrator. 13. Delete a review property. Primary Actor: Store Administrator. 14. Show reviews of a product. Primary Actor: Customer, Store Administrator. 15. Show reviews of a customer. Primary Actor: Customer. 16. Add a product to the wish list. Primary Actor: Customer. 17. Remove a product from the wish list. Primary Actor: Customer. 18. Add a product to the compare list. Primary Actor: Customer. 19. Remove a product from the compare list. Primary Actor: Customer. 151

20. Share wish list. Primary Actor: Customer. 21. Subscribe to a product price alert. Primary Actor: Customer. 22. Subscribe to a product stock alert. Primary Actor: Customer. 23. Show wish list. Primary Actor: Customer. 24. Show ready to compare products. Primary Actor: Customer. 25. Show recently compared products. Primary Actor: Customer. 26. Show recently viewed products. Primary Actor: Customer. 27. Show compare. Primary Actor: Customer. 28. Add a newsletter template. Primary Actor: Store Administrator. 29. Edit a newsletter template. Primary Actor: Store Administrator. 30. Delete a newsletter template. Primary Actor: Store Administrator. 31. Add a newsletter. Primary Actor: Store Administrator. 32. Edit a newsletter. Primary Actor: Store Administrator. 33. Subscribe to the newsletter. Primary Actor: Customer. 34. Unsubscribe from the newsletter. Primary Actor: Customer. 35. Delete a newsletter subscription. Primary Actor: Store Administrator. 36. Unsubscribe a newsletter subscription. Primary Actor: Store Administrator. 37. Show shopping cart. Primary Actor: Customer. 38. Download a product. Primary Actor: Customer. 39. Show downloadable products of a customer. Primary Actor: Customer. 40. Tell to a friend. Primary Actor: Customer. 41. View product information. Primary Actor: Customer. 42. Search products. Primary Actor: Customer. 43. Show the best purchased products. Primary Actor: Customer. 44. Reset the temporal information. Primary Actor: System.

Online catalog
1. Place an order. Primary Actor: Customer. 2. Checkout an order with multiple addresses. Primary Actor: Customer. 3. Add an order. Primary Actor: Store Administrator. 4. Cancel an order. Primary Actor: Store Administrator. 5. Hold an order. Primary Actor: Store Administrator. 6. Unhold an order. Primary Actor: Store Administrator. 7. Reorder. Primary Actor: Customer, Store Administrator. 8. Add a gift message to a placed order. Primary Actor: Store Administrator. 9. Print an Order. Primary Actor: Customer. 10. Send order information by email. Primary Actor: Store Administrator. 11. Show previous orders of a customer. Primary Actor: . 12. Add an invoice. Primary Actor: Store Administrator. 13. Register an invoice payment. Primary Actor: Store Administrator. 152

14. Cancel an invoice. Primary Actor: Store Administrator. 15. Add a shipment. Primary Actor: Store Administrator. 16. Add a refund. Primary Actor: Store Administrator. 17. Cancel a refund. Primary Actor: Store Administrator. 18. Add a comment to an order, invoice, shipment or refund.. Primary Actor: Store Administrator.

Store Reports
1. Show the sales report. Primary Actor: Store Administrator. 2. Show the tax report. Primary Actor: Store Administrator. 3. Show the shipping report. Primary Actor: Store Administrator. 4. Show the invoices report. Primary Actor: Store Administrator. 5. Show the refunds report. Primary Actor: Store Administrator. 6. Show the coupon codes report. Primary Actor: Store Administrator. 7. Show the products in carts report. Primary Actor: Store Administrator. 8. Show the abandoned carts report. Primary Actor: Store Administrator. 9. Show the bestseller products report. Primary Actor: Store Administrator. 10. Show the ordered products report. Primary Actor: Store Administrator. 11. Show the most viewed products report. Primary Actor: Store Administrator. 12. Show the stock of products report. Primary Actor: Store Administrator. 13. Show the downloads report. Primary Actor: Store Administrator. 14. Show the new customer accounts report. Primary Actor: Store Administrator. 15. Show the customers by orders total report. Primary Actor: Store Administrator. 16. Show the customers by number of orders report. Primary Actor: Store Administrator. 17. Show the customer reviews report. Primary Actor: Store Administrator. 18. Show the product reviews report. Primary Actor: Store Administrator. 19. Show the tags by customer report. Primary Actor: Store Administrator. 20. Show the tags by product report. Primary Actor: Store Administrator. 21. Show the popular tags report. Primary Actor: Store Administrator. 22. Show the search terms report. Primary Actor: Store Administrator.

153

3.4 Store Conguration


Use Case

3.4.1

Add a website

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a website Main success scenario 1. The store administrator provides the websites details. 2. The system saves the new website. [NewWebsite]
Use Case

3.4.2

Edit a website

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a website Main success scenario 1. The store administrator selects the website to be edited. 2. The store administrator provides the new websites details. 3. The system saves the new website. [EditWebsite]
Use Case

3.4.3

Delete a website

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a website Main success scenario 1. 2. 3. 4. The store administrator selects the website to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the website The system deletes the website. [DeleteWebsite]

Extensions 2a.The store administrator does not want to delete the website 2a1. The use case ends

154

Use Case

3.4.4

Select the default website

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to change the default website Main success scenario 1. The store administrator selects the website which will become the default website 2. The system updates the default website [SetDefaultWebsite]
Use Case

3.4.5

Add a store

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a store Main success scenario 1. The store administrator provides the stores details. 2. The system saves the new store. [NewStore]
Use Case

3.4.6

Edit a store

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a store Main success scenario 1. The store administrator selects the store to be edited. 2. The store administrator provides the new stores details. 3. The system saves the new store. [EditStore]
Use Case

3.4.7

Delete a store

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a store Main success scenario 1. The store administrator selects the store to be deleted. 2. The system asks the store administrator a conrmation 3. The store administrator conrms that he wants to delete the store 155

4. The system deletes the store. [DeleteStore] Extensions 2a.The store administrator does not want to delete the store 2a1. The use case ends
Use Case

3.4.8

Select the default store of a website

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to change the default store of a website Main success scenario 1. The store administrator selects the website whose default store will be changed. 2. The store administrator selects the store which will become the default store of this website. 3. The system updates the default website [SetDefaultStoreOfWebsite]
Use Case

3.4.9

Add an store view

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add an store view Main success scenario 1. The store administrator provides the store view details. 2. The system saves the new store view. [NewStoreView]
Use Case

3.4.10

Edit an store view

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit an store view Main success scenario 1. The store administrator selects the store view to be edited. 2. The store administrator provides the new store view details. 3. The system saves the new store view. [EditStoreView]
Use Case

3.4.11

Delete an store view


156

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete an store view Main success scenario 1. 2. 3. 4. The store administrator selects the store view to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the store view The system deletes the store view. [DeleteStoreView]

Extensions 2a.The store administrator does not want to delete the store view. 2a1. The use case ends
Use Case

3.4.12

Select the default store view of a store

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to change the default store view of a store Main success scenario 1. The store administrator selects the store whose default store view will be changed. 2. The store administrator selects the store view which will become the default store view of this store. 3. The system updates the default store view of the store [SetDefaultStoreViewOfStore]
Use Case

3.4.13

Select the default language

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to change the default language Main success scenario 1. The store administrator selects the language which will become the default language 2. The system updates the default language [SetDefaultLanguage] Extensions 2a.The system administrator wants to dene the default language for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2

157

Use Case

3.4.14

Change the catalog conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the catalog conguration. Main success scenario 1. 2. 3. 4. The system displays the current catalog conguration values. The store administrator provides the new values for the catalog conguration. The system validates that the new values are correct The system saves the new values [ChangeCatalogConguration]

Extensions 2a.The system administrator wants to change the catalog conguration values for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2
Use Case

3.4.15

Change the stock conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the stock conguration. Main success scenario 1. 2. 3. 4. The system displays the current stock conguration values. The store administrator provides the new values for the stock conguration. The system validates that the new values are correct The system saves the new values [ChangeStockConguration]

Use Case

3.4.16

Change the wishlist conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the wishlist conguration. Main success scenario 1. 2. 3. 4. The system displays the current wishlist conguration values. The store administrator provides the new values for the wishlist conguration. The system validates that the new values are correct The system saves the new values [ChangeWishListConguration]

158

Extensions 2a.The system administrator wants to change the wishlist conguration values for only a website 2a1. The system displays the available websites 2a2. The system administrator selects a website 2a3. The use case continues at step 2
Use Case

3.4.17

Change the sales conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the sales conguration. Main success scenario 1. 2. 3. 4. The system displays the current sales conguration values. The store administrator provides the new values for the sales conguration. The system validates that the new values are correct The system saves the new values [ChangeSalesConguration]

Extensions 2a.The system administrator wants to change the sales conguration values for only a website 2a1. The system displays the available websites 2a2. The system administrator selects a website 2a3. The use case continues at step 2
Use Case

3.4.18

Change the customer conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the customer conguration. Main success scenario 1. 2. 3. 4. The system displays the current customer conguration values. The store administrator provides the new values for the sales conguration. The system validates that the new values are correct The system saves the new values [ChangeCustomerConguration]

Extensions 2a.The system administrator wants to change the sales conguration values for only an store view. 2a1. The system displays the available store views 2a2. The system administrator selects an store view 2a3. The use case continues at step 2

159

Use Case

3.4.19

Change the tax conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the tax conguration. Main success scenario 1. 2. 3. 4. The system displays the current tax conguration values. The store administrator provides the new values for the tax conguration. The system validates that the new values are correct The system saves the new values [ChangeTaxConguration]

Extensions 2a.The system administrator wants to change the tax conguration values for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2
Use Case

3.4.20

Change the shipping conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the shipping conguration. Main success scenario 1. 2. 3. 4. The system displays the current shipping conguration values. The store administrator provides the new values for the shipping conguration. The system validates that the new values are correct The system saves the new values [ChangeShippingConguration]

Extensions 2a.The system administrator wants to change the shipping conguration values for only a website 2a1. The system displays the available websites 2a2. The system administrator selects a website 2a3. The use case continues at step 2
Use Case

3.4.21

Change the tell to a friend conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the tell to a friend conguration. Main success scenario 160

1. 2. 3. 4.

The system displays the current tell to a friend conguration values. The store administrator provides the new values for the tell to a friend conguration. The system validates that the new values are correct The system saves the new values [ChangeTellToAFriendConguration]

Extensions 2a.The system administrator wants to change the shipping conguration values for only a store view 2a1. The system displays the available store views 2a2. The system administrator selects a store view 2a3. The use case continues at step 2
Use Case

3.4.22

Change the currency conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the currency conguration Main success scenario 1. The system displays the enabled currencies. 2. The store administrator selects a base currency, the allowed currencies and the default currency. 3. The system validates that the new values are correct 4. The system saves the new values [ChangeCurrencyConguration] Extensions 2a.The system administrator wants to change the currency conguration for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2 3a.A selected currency is not enabled or the selected default currency is not one of the selected allowed currencies 3a1. The system informes the store administrator 3a2. The use case continues at step 2
Use Case

3.4.23

Change the enabled currencies

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the enabled system currencies. Main success scenario 1. The system displays all the currencies.

161

2. The store administrator selects a base currency, the allowed currencies and the default currency. 3. The system validates that the new values are correct 4. The system saves the new values [ChangeEnabledCurrencies] Extensions 3a.Some of the selected currencies are currently a base, allowed or default currency in some store view. 3a1. The system informes the store administrator 3a2. The use case continues at step 2
Use Case

3.4.24

Update currency rates

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to updata automatically via Internet the change values for currency rates Main success scenario 1. The system connects to the change information server. 2. The value change is automatically updated for all the currencies [UpdateCurrencyValue]
Use Case

3.4.25

Change the geographical conguration values

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants tho change the conguration related about countries. Main success scenario 1. 2. 3. 4. The system displays all the countries The store administrator selects the allowed countries and a default country. The system validates that the new values are correct The system saves the new values [ChangeGeographicalConguration]

Extensions 2a.The system administrator wants to change the geographical conguration for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2 3a.The selected default country is not one of the selected allowed countries. 3a1. The system informes the store administrator 3a2. The use case continues at step 2

162

Use Case

3.4.26

Change shipping method values

Primary Actor: System Administrator Precondition: None Trigger: The store administrator wants to change the conguration values of a shipping method Main success scenario 1. The system displays the shipping methods and its current values. 2. The sytem administrator provides the new values for the congurable attributes that he wants to change. 3. The system validates that the new values are correct 4. The system saves the new values [EditShippingMethods] 5. The system displays the new values of the shipping methods. Extensions 2a.The system administrator wants to change shipping method values for only a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2
Use Case

3.4.27

Change payment method values

Primary Actor: System Administrator Precondition: None Trigger: The store administrator wants to change the conguration values of a payment method Main success scenario 1. The system displays the payment methods and its current values. 2. The sytem administrator provides the new values for the congurable attributes that he wants to change. 3. The system validats that the new values are correct 4. The system saves the new values [EditPaymentMethods] 5. The system displays the new values of the payment methods. Extensions 2a.The system administrator wants to change shipping method values only for a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2
Use Case

3.4.28

Add a customer tax class

Primary Actor: Store Administrator Precondition: None 163

Trigger: The store administrator wants to add a customer tax class Main success scenario 1. The store administrator provides the customer tax class name. 2. The system saves the new customer tax class. [NewCustomerTaxClass]
Use Case

3.4.29

Edit a customer tax class

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a customer tax class Main success scenario 1. The store administrator selects the customer tax class to be edited. 2. The store administrator provides the new customer tax class name. 3. The system saves the new customer tax class. [EditCustomerTaxClass]
Use Case

3.4.30

Delete a customer tax class

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a customer tax class Main success scenario 1. 2. 3. 4. The store administrator selects the customer tax class to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the customer tax class The system deletes the customer tax class. [DeleteCustomerTaxClass]

Extensions 2a.The store administrator does not want to delete the customer tax class 2a1. The use case ends
Use Case

3.4.31

Add a product tax class

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a product tax class Main success scenario 1. The store administrator provides the product tax class name. 2. The system saves the new product tax class. 164

[NewProductTaxClass]
Use Case

3.4.32

Edit a product tax class

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a product tax class Main success scenario 1. The store administrator selects the product tax class to be edited. 2. The store administrator provides the new product tax class name. 3. The system saves the changes. [EditProductTaxClass]
Use Case

3.4.33

Delete a product tax class

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a product tax class Main success scenario 1. 2. 3. 4. The store administrator selects the product tax class to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the product tax class The system deletes the product tax class. [DeleteProductTaxClass]

Extensions 2a.The store administrator does not want to delete the product tax class 2a1. The use case ends
Use Case

3.4.34

Add a tax rate

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a tax rate Main success scenario 1. The store administrator provides the details of the new.tax rate 2. The system validates that the data is correct. 3. The system saves the new tax rate. [NewTaxRate]

165

Use Case

3.4.35

Edit a tax rate

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a tax rate Main success scenario 1. 2. 3. 4. The store administrator selects the tax rate to be edited. The store administrator provides the new details of the tax rate. The system validates that the data is correct. The system saves the changes. [EditTaxRate]

Use Case

3.4.36

Delete a tax rate

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a tax rate Main success scenario 1. 2. 3. 4. The store administrator selects the tax rate to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the tax rate The system deletes the tax rate. [DeleteTaxRate]

Extensions 2a.The store administrator doesnt want to delete the tax rate 2a1. The use case ends
Use Case

3.4.37

Add a tax rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a tax rule Main success scenario 1. The store administrator provides the details of the new.tax rule 2. The system validates that the data is correct. 3. The system saves the new tax rule. [NewTaxRule]
Use Case

3.4.38

Edit a tax rule

166

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a tax rule Main success scenario 1. 2. 3. 4. The store administrator selects the tax rate to be edited. The store administrator provides the new details of the tax rule. The system validates that the data is correct. The system saves the changes. [EditTaxRule]

Use Case

3.4.39

Delete a tax rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a tax rule Main success scenario 1. 2. 3. 4. The store administrator selects the tax rule to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the tax rule The system deletes the tax rule. [DeleteTaxRule]

Extensions 2a.The store administrator doesnt want to delete the tax rule 2a1. The use case ends

167

3.5 Customers
Use Case

3.5.1

Create a Customer

Primary Actor: Customer, Store Administrator Precondition: None Trigger: A customer wants to open an account in the store Main success scenario 1. The customer or the store administrator provides the required customer data 2. The system validates the customer data 3. The system saves the new account [CreateCustomer] Extensions 1a.The primary actor is the store administrator 1a1. The store administrator provides also the website where this customer account is associated
Use Case

3.5.2

Change password

Primary Actor: Customer Precondition: The customer is logged in Trigger: A customer wants to change his password Main success scenario 1. 2. 3. 4. The customer provides the old password The customer provides the new password twice The system validates that the data is correct The system saves the changes [PasswordChange]

Use Case

3.5.3

Change customer details

Primary Actor: Customer Precondition: The customer is logged in Trigger: A customer wants to change its customer details Main success scenario 1. The customer provides the new customer details 2. The system validates that the data is correct 3. The system saves the changes [EditCustomerDetails]

168

Use Case

3.5.4

Administrate address book

Primary Actor: Customer Precondition: The customer is logged in Trigger: A customer wants to view or change the address book Main success scenario 1. 2. 3. 4. The system displays the current address book entries of the customer. The customer selects an address book entry to be edited The system validates that the data is correct The system saves the changes and displays the new address book [EditCustomerAddress] The customer repeats steps 1-4 until he is done. Extensions 2a.The customer doesnt want tho change the address book 2a1. The use case ends. 2b.The customer wants to add a new address book entry 2b1. The user provides the required data [NewCustomerAddress] 2b2. The use case continues at step 3 2c.The customer wants to delete an address book entry 2c1. The user selects the address book entry [DeleteCustomerAddress] 2c2. The use case continues at step 3 2d.The customer wants to change the default shipping address 2d1. The customer selects the new default shipping address [DefaultDeliveryAddressChange] 2d2. The use case continues at step 3 2e.The customer wants to change the default billing address 2e1. The customer selects the new default billing address [DefaultBillingAddressChange] 2e2. The use case continues at step 3
Use Case

3.5.5

Edit a customer

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a customer Main success scenario 1. 2. 3. 4. The store administrator selects the customer to be edited. The store administrator provides the new details of the customer. The system validates that the data is correct. The system saves the changes. [EditCustomer]

169

Use Case

3.5.6

Delete a customer

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a customer Main success scenario 1. The store administrator selects the customer to be deleted. 2. The system asks the store administrator a conrmation 3. The store administrator conrms that he wants to delete the customer 4. The system deletes the customer and his addresses, reviews, notication subscriptions, shopping carts, buying activity lists and tags. [DeleteCustomer] Extensions 2a.The store administrator doesnt want to delete the customer 2a1. The use case ends
Use Case

3.5.7

Show account information

Primary Actor: Customer Precondition: The customer is logged in Trigger: The customer wants to visualize his account information. Main success scenario 1. The system shows the customers account information. [ShowAccountInformation]
Use Case

3.5.8

Show address book

Primary Actor: Customer Precondition: The customer is logged in Trigger: The customer wants to visualize his address book. Main success scenario 1. The system shows the customers registered addresses. [ShowAddresses]
Use Case

3.5.9

Add a customer group

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a customer group

170

Main success scenario 1. The store administrator provides the details of the new customer group. 2. The system validates that the data is correct. 3. The system saves the new customer group. [NewCustomerGroup]
Use Case

3.5.10

Edit a customer group

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a customer group Main success scenario 1. 2. 3. 4. The store administrator selects the customer group to be edited. The store administrator provides the new details of the customer group. The system validates that the data is correct. The system saves the changes. [EditCustomerGroup]

Use Case

3.5.11

Delete a customer group

Primary Actor: Store Administrator Precondition: More than three customer groups extist in the system Trigger: The store administrator wants to delete a customer group Main success scenario 1. 2. 3. 4. The store administrator selects the customer group to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the customer group. The system deletes the customer group. [DeleteCustomerGroup]

Extensions 2a.The store administrator doesnt want to delete the customer group. 2a1. The use case ends
Use Case

3.5.12

Add an administrator

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add an administrator Main success scenario 1. The store administrator provides the details of the new administrator, including its role. 2. The system validates that the data is correct. 171

3. The system saves the new administrator. [NewAdministrator]


Use Case

3.5.13

Edit an administrator

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit an administrator Main success scenario 1. 2. 3. 4. The store administrator selects the administrator to be edited. The store administrator provides the new details of the administrator, including its role. The system validates that the data is correct. The system saves the changes. [EditAdministrator]

Use Case

3.5.14

Delete an administrator

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a administrator Main success scenario 1. 2. 3. 4. The store administrator selects the administrator to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the administrator. The system deletes the administrator. [DeleteAdministrator]

Extensions 2a.The store administrator doesnt want to delete the administrator. 2a1. The use case ends 4a.The store administrator wants to delete himself 4a1. The system informs the store administrator that he cant delete himself. 4a2. The use case ends.
Use Case

3.5.15

Add a role

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a role Main success scenario 1. The store administrator provides the details of the new role. 2. The system validates that the data is correct. 3. The system saves the new role. 172

[NewRole]
Use Case

3.5.16

Edit a role

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a role Main success scenario 1. 2. 3. 4. The store administrator selects the role to be edited. The store administrator provides the new details of the role. The system validates that the data is correct. The system saves the changes. [EditRole]

Use Case

3.5.17

Delete a role

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a role Main success scenario 1. 2. 3. 4. The store administrator selects the role to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the role. The system deletes the role. [DeleteRole]

Extensions 2a.The store administrator doesnt want to delete the role. 2a1. The use case ends 4a.The store administrator wants to delete the role he has assigned 4a1. The system informs the store administrator that he cant delete the role he has assigned. 4a2. The use case ends.
Use Case

3.5.18

Log In

Primary Actor: Customer Precondition: The customer is not logged in Trigger: A customer logs in the system Main success scenario 1. The customer introduces their identication data 2. The system validates the identication data 3. The customer becomes the owner of the current session [LogIn] 173

Extensions 3a. The customer has a shopping cart from a previous session 3a1. The previous shopping cart is restored [RestorePreviousShoppingCart] 3b. The customer has a non-empty compare list, a recently compared products list or a recently viewed products list from a previous session 3b1. The previous compared, recently compared a recently viewed products are restored [RestorePreviousProductLists]
Use Case

3.5.19

Log Out

Primary Actor: Customer Precondition: The customer is logged in Trigger: A customer logs out from the system Main success scenario 1. The current session becomes anonymous [LogOut] Extensions 1a. The customer has a non empty compare list, recently compared products list or recently viewed products list. 1a1. The compared, recently compared and recently viewed products are saved [SaveCurrentProductLists]
Use Case

3.5.20

Open session

Primary Actor: Customer Precondition: None Trigger: A customer starts using the system Main success scenario 1. The system creates an anonymous session [NewSession]
Use Case

3.5.21

Finish session

Primary Actor: Customer Precondition: None Trigger: A customer nishes using the system Main success scenario 1. The system deletes the current session [DeleteSession]

174

Extensions 1a.The customer is logged in and the session has a non empty shopping cart. 1b. The customer has a non empty compare list, recently compared products list or recently viewed products list. 1b1. The compared, recently compared and recently viewed products are saved [SaveCurrentProductLists]
Use Case

3.5.22

Change the current Website

Primary Actor: Customer Precondition: None Trigger: A customer wants to change the current website of the session Main success scenario 1. The customer selects the website which will become the current website 2. The system updates the current website [SetCurrentWebsite]
Use Case

3.5.23

Change the current Store

Primary Actor: Customer Precondition: None Trigger: A customer wants to change the current store of the session Main success scenario 1. The customer selects the store which will become the current store 2. The system updates the current store [SetCurrentStore]
Use Case

3.5.24

Change the current Store View

Primary Actor: Customer Precondition: None Trigger: A customer wants to change the current store view of the session Main success scenario 1. The customer selects the store view which will become the current store view 2. The system updates the current store view [SetCurrentStoreView]
Use Case

3.5.25

Change the current Currency

Primary Actor: Customer 175

Precondition: None Trigger: A customer wants to change the current currency of the session Main success scenario 1. The customer selects the currency which will become the current currency 2. The system updates the current currency [SetCurrentCurrency]

176

3.6 Store Administration


Use Case

3.6.1

Add a product

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a product to the store catalog Main success scenario 1. The store administrator provides the product type and the attribute set associated. 2. The system displays the attributes that can be given a value for this product, including product properties and corresponding simple attributes [ShowProductPropertiesAndAbleToRateAttributes] 3. The store administrator provides the details of the new product. 4. The system validates that the data is correct. 5. The system saves the new product. [NewProduct] Extensions 3a.The system administrator wants to redene some details for a restricted scope 3a1. The system displays the available scopes 3a2. The system administrator selects a scope 3a3. The use case continues at step 2. 5a.The store administrator wants to continue editing the product properties 5a1. The use case continues at step 2.
Use Case

3.6.2

Edit a product

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a product Main success scenario 1. 2. 3. 4. The store administrator selects the product to be edited. The store administrator provides the new details of the product. The system validates that the data is correct. The system saves the changes. [EditProduct]

Extensions 2a.The system administrator wants to redene some details for a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2

177

Use Case

3.6.3

Delete a product

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a product Main success scenario 1. The store administrator selects the product to be deleted. 2. The system asks the store administrator a conrmation 3. The store administrator conrms that he wants to delete the product 4. The system deletes the product and the values associated to its attributes, if they are not associated to any other product. [DeleteProduct] Extensions 2a.The store administrator doesnt want to delete the product 2a1. The use case ends
Use Case

3.6.4

Add a product category

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a category Main success scenario 1. The store administrator provides the details of the new category, including its parent category, if any: 2. The system validates that the data is correct. 3. The system saves the new category. [NewCategory] Extensions 1a.The store administrator wants to redene some details for a restricted scope 1a1. The system displays the available scopes 1a2. The store administrator selects a scope 1a3. The use case continues at step 1
Use Case

3.6.5

Edit a product category

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a category Main success scenario 1. The store administrator selects the category to be edited. 2. The store administrator provides the new details of the category. 178

3. The system validates that the data is correct. 4. The system saves the changes. [EditCategory] Extensions 2a.The store administrator wants to redene some details for a restricted scope 2a1. The system displays the available store views 2a2. The store administrator selects a store view 2a3. The store administrator selects the category to be edited, within the available categories in that store view 2a4. The use case continues at step 1
Use Case

3.6.6

Move a product category

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to change the placement of a category in the category hierarchy Main success scenario 1. 2. 3. 4. The store administrator selects the category to be moved. The store administrator indicates the new parent category, if any. The system validates that the data is correct. The system saves the new placement. [MoveCategory]

Use Case

3.6.7

Delete a product category

Primary Actor: Store Administrator Precondition: The selected category is not the root category of any store. Trigger: The store administrator wants to delete a category Main success scenario 1. The store administrator selects the category to be deleted. 2. The system asks the store administrator a conrmation 3. The store administrator conrms that he wants to delete the category 4. The system deletes the category and all its subcategories. Products of those categories do not belong to them no more. [DeleteCategory] Extensions 2a.The store administrator doesnt want to delete the category 2a1. The use case ends
Use Case

3.6.8

Add an attribute
179

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add an attribute Main success scenario 1. The store administrator provides the attribute type. 2. The system displays the properties that can be dened for this product [ShowAttributeProperties] 3. The store administrator provides the details of the new attribute 4. The system validates that the data is correct. 5. The system saves the new attribute. [NewAttribute]
Use Case

3.6.9

Edit an attribute

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit an attribute Main success scenario 1. 2. 3. 4. The store administrator selects the attribute to be edited. The store administrator provides the new details of the attribute. The system validates that the data is correct. The system saves the changes. [EditAttribute]

Use Case

3.6.10

Delete an attribute

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete an attribute Main success scenario 1. 2. 3. 4. The store administrator selects the attribute to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the attribute The system deletes the attribute. [DeleteAttribute]

Extensions 2a.The store administrator doesnt want to delete the attribute 2a1. The use case ends
Use Case

3.6.11

Add an attribute set


180

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add an attribute set Main success scenario 1. The store administrator provides the details of the new attribute set. 2. The system validates that the data is correct. 3. The system saves the new attribute set. [NewAttributeSet]
Use Case

3.6.12

Edit an attribute set

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit an attribute set Main success scenario 1. 2. 3. 4. 5. The store administrator selects the attribute set to be edited. The system shows the attributes associated to the attribute set The store administrator provides the new details of the attribute set. The system validates that the data is correct. The system saves the changes. [EditAttributeSet]

Extensions 3a.The store administrator wants to remove an attribute from the attribute set 3a1. The store administrator selects the attribute to be removed. 3a2. The use case continues at step 2 3b.The store administrator wants to add an attribute to the attribute set 3b1. The store administrator selects the attribute to be added. 3b2. The use case continues at step 2
Use Case

3.6.13

Delete an attribute set

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete an attribute set Main success scenario 1. 2. 3. 4. The store administrator selects the attribute set to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the attribute set. The system deletes the attribute set. [DeleteAttributeSet]

Extensions 2a.The store administrator doesnt want to delete the attribute set. 181

2a1. The use case ends


Use Case

3.6.14

Administrate tier prices of a product

Primary Actor: Store Administrator Precondition: At least one product is created in the system Trigger: A customer wants to view or change the tier prices of a product Main success scenario 1. 2. 3. 4. 5. The store administrator selects a product The system displays the current tier prices of the selected product. The store administrator selects a tier price to be edited The system validates that the data is correct The system saves the changes and displays the new product tier prices [EditTierPrice] The customer repeats steps 2-5 until he is done. Extensions 3a.The customer doesnt want tho change the tier price 3a1. The use case ends. 3b.The customer wants to add a new tier price 3b1. The user provides the required data [NewTierPrice] 3b2. The use case continues at step 4 3c.The customer wants to delete a tier price 3c1. The user selects the tier price [DeleteTierPrice] 3c2. The use case continues at step 4
Use Case

3.6.15

Add a catalog price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a catalog price rule Main success scenario 1. The store administrator provides the details of the new catalog price rule and its condition. 2. The system validates that the data is correct. 3. The system saves the new catalog price rule. [NewCatalogPriceRule] Extensions 3a.The store administrator wants to apply now the rule to the product prices 3a1. The system saves the new catalog price rule [NewCatalogPriceRule] 3a2. The system applies the new rule to applicable products in the catalog [ApplyCatalogPriceRule] 3a3. The use case ends. 182

Use Case

3.6.16

Edit a catalog price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a catalog price rule Main success scenario 1. 2. 3. 4. The store administrator selects the catalog price rule to be edited. The store administrator provides the new details of the catalog price rule and its condition. The system validates that the data is correct. The system saves the changes. [EditCatalogPriceRule]

Extensions 4a.The store administrator wants to apply now the rule to the product prices 4a1. The system saves the changes [EditCatalogPriceRule] 4a2. The system applies the new rule to applicable products in the catalog [ApplyCatalogPriceRule] 4a3. The use case ends.
Use Case

3.6.17

Delete a catalog price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a catalog price rule Main success scenario 1. 2. 3. 4. The store administrator selects the catalog price rule to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the catalog price rule. The system deletes the catalog price rule and its condition. [DeleteCatalogPriceRule]

Extensions 2a.The store administrator doesnt want to delete the catalog price rule. 2a1. The use case ends
Use Case

3.6.18

Add a shopping cart price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a shopping cart price rule Main success scenario

183

1. The store administrator provides the details of the new shopping cart price rule, including its labels and its condition. 2. The system validates that the data is correct. 3. The system saves the new shopping cart price rule. [NewShoppingCartPriceRule]
Use Case

3.6.19

Edit a shopping cart price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a shopping cart price rule Main success scenario 1. The store administrator selects the shopping cart price rule to be edited. 2. The store administrator provides the new details of the shopping cart price rule, including its labels and its condition. 3. The system validates that the data is correct. 4. The system saves the changes. [EditShoppingCartPriceRule]
Use Case

3.6.20

Delete a shopping cart price rule

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a shopping cart price rule Main success scenario 1. 2. 3. 4. The store administrator selects the shopping cart price rule to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the shopping cart price rule. The system deletes the shopping cart price rule and its condition. [DeleteShoppingCartPriceRule]

Extensions 2a.The store administrator doesnt want to delete the shopping cart price rule. 2a1. The use case ends

184

3.7 Additional Activities


Use Case

3.7.1

Tag a product

Primary Actor: Customer Precondition: The customer is logged in.The product is enabled in the current website. Trigger: A customer wants to add a tag to a product Main success scenario 1. The customer selects the product. 2. The customer gives the tag name. 3. The system saves the association of this tag to a product by the customer in the current store view
Use Case

3.7.2

Add a tag

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a tag Main success scenario 1. The store administrator provides the details of the new tag. 2. The system validates that the data is correct. 3. The system saves the new tag. [NewTag] Extensions 1a.The system administrator wants to change shipping method values only for a restricted scope 1a1. The system displays the available scopes 1a2. The system administrator selects a scope 1a3. The use case continues at step 1
Use Case

3.7.3

Edit a tag

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a tag Main success scenario 1. The store administrator selects the tag to be edited. 2. The store administrator provides the new details of the tag, including the products tagged by administrators with this tag. 3. The system validates that the data is correct. 4. The system saves the changes. 185

[EditTag] Extensions 2a.The system administrator wants to change shipping method values only for a restricted scope 2a1. The system displays the available scopes 2a2. The system administrator selects a scope 2a3. The use case continues at step 2
Use Case

3.7.4

Delete a tag

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a tag Main success scenario 1. 2. 3. 4. The store administrator selects the tag to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the tag. The system deletes the tag. [DeleteTag]

Extensions 2a.The store administrator doesnt want to delete the tag. 2a1. The use case ends
Use Case

3.7.5

Show tags of a customer

Primary Actor: Customer Precondition: The customer is logged in Trigger: The Customer wants to visualize the tags that he has added Main success scenario 1. The system shows the tags added by the customer [ShowTagsOfCustomer]
Use Case

3.7.6

Show most popular tags

Primary Actor: Customer Precondition: None Trigger: The Customer enters to the system Main success scenario 1. The system shows the most popular tags in the current store view, stressing those who are the most used. [ShowPopularTags] 186

Use Case

3.7.7

Show all tags

Primary Actor: Customer Precondition: None Trigger: The Customer enters to the system Main success scenario 1. The system shows all the tags in the current store view, stressing those who are the most used. [ShowAllTags]
Use Case

3.7.8

Add a review

Primary Actor: Customer, Store Administrator Precondition: The product is enabled in the current website. Trigger: A customer or store administrator wants to write a review of a product Main success scenario 1. The customer or store administrator selects a product 2. The customer or store administrator provides the content of review and a score for each property [NewReview] 3. The system validates that the data is correct 4. The system saves the review Extensions 2a.The primary actor is an Store Administrator 2a1. The store administrator provides also the initial review status and the store views where it is visible [NewAdministratorReview] 2a2. The use case continues at step 3.
Use Case

3.7.9

Edit a review

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a review Main success scenario 1. The store administrator selects the review to be edited. 2. The store administrator provides the new details of the review, including its status and rating scores. 3. The system validates that the data is correct. 4. The system saves the changes. [EditReview]

187

Use Case

3.7.10

Delete a review

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a review Main success scenario 1. 2. 3. 4. The store administrator selects the review to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the review. The system deletes the review. [DeleteReview]

Extensions 2a.The store administrator doesnt want to delete the review. 2a1. The use case ends
Use Case

3.7.11

Add a review property

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a property Main success scenario 1. The store administrator provides the details of the new property. 2. The system validates that the data is correct. 3. The system saves the new property. [NewProperty]
Use Case

3.7.12

Edit a review property

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a property Main success scenario 1. 2. 3. 4. The store administrator selects the property to be edited. The store administrator provides the new details of the property. The system validates that the data is correct. The system saves the changes. [EditProperty]

Use Case

3.7.13

Delete a review property

188

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a property Main success scenario 1. 2. 3. 4. The store administrator selects the property to be deleted. The system asks the store administrator a conrmation The store administrator conrms that he wants to delete the property. The system deletes the property. [DeleteProperty]

Extensions 2a.The store administrator doesnt want to delete the property. 2a1. The use case ends
Use Case

3.7.14

Show reviews of a product

Primary Actor: Customer, Store Administrator Precondition: The customer is logged in Trigger: The Customer or the Store Administrator wants to visualize the reviews of a product Main success scenario 1. The store administrator or the customer selects a product. 2. The system shows the reviews of the selected product. [ShowReviewsOfProduct]
Use Case

3.7.15

Show reviews of a customer

Primary Actor: Customer Precondition: The customer is logged in Trigger: The Customer wants to visualize the reviews that he has made Main success scenario 1. The system shows the reviews written by the customer [ShowReviewsOfCustomer]
Use Case

3.7.16

Add a product to the wish list

Primary Actor: Customer Precondition: The product is enabled in the current website. Trigger: A customer wants to add a product to the wish list Main success scenario 1. The customer selects a product 2. The system adds this product to the wish list 189

[AddProductToWishlist] 3. The system shows the costumers wish list. Extensions 1a.The product is already in the wish list 1a1. The use case continues at step 3 3a.The customer wants to add or edit a comment to a product in the wish list. 3a1. The customer provides the comment text. 3a2. The system saves the comment. [AddCommentToWishlistItem] 3b.The customer wants to remove a comment from a product in the wish list. 3b1. The system deletes the comment. [RemoveCommentFromWishlistItem]
Use Case

3.7.17

Remove a product from the wish list

Primary Actor: Customer Precondition: The customers wish list contains one product at least. Trigger: A customer wants to remove a product from the wish list Main success scenario 1. The customer selects a product from the wish list 2. The system removes this product from the wish list [RemoveProductFromWishlist]
Use Case

3.7.18

Add a product to the compare list

Primary Actor: Customer Precondition: The product is enabled in the current website Trigger: A customer wants to add a product to the compare list Main success scenario 1. The customer selects a product 2. The system adds this product to the compare list [AddProductToCompareList] Extensions 1a.The product is already in the compare list 1a1. End of the use case.
Use Case

3.7.19

Remove a product from the compare list

Primary Actor: Customer Precondition: The customers compare list contains one product at least. Trigger: A customer wants to remove a product from the compare list

190

Main success scenario 1. The customer selects a product from the compare list 2. The system removes this product from the compare list [RemoveProductFromCompareList]
Use Case

3.7.20

Share wish list

Primary Actor: Customer Precondition: The wish list has at least one product Trigger: A customer wants to share its wish list information Main success scenario 1. The customer provides multiple email addresses and a message. 2. The system sends an email to each address with the message and the customers wish list information.
Use Case

3.7.21

Subscribe to a product price alert

Primary Actor: Customer Precondition: The customer is logged in. Product alerts are enabled for the current website.The product is enabled in the current website. Trigger: A customer wants to subscribe himself to a product price alert Main success scenario 1. The customer selects the product 2. The system signs up the customer for the price alerts of that product. [SingUpForPriceAlert]
Use Case

3.7.22

Subscribe to a product stock alert

Primary Actor: Customer Precondition: The customer is logged in. Product alerts are enabled for the current website and the product is out of stock.The product is enabled in the current website. Trigger: A customer wants to subscribe himself to a product stock alert Main success scenario 1. The customer selects the product 2. The system signs up the customer for the stock alerts of that product. [SingUpForStockAlert]
Use Case

3.7.23

Show wish list

Primary Actor: Customer

191

Precondition: The customer is logged in Trigger: The customer wants to visualize the products in his wish list. Main success scenario 1. The system shows the products in the customers wish list. [ShowWishList]
Use Case

3.7.24

Show ready to compare products

Primary Actor: Customer Precondition: None Trigger: The customer wants to visualize the products in his ready to compare list. Main success scenario 1. The system shows the products in the customers ready to compare list. [ShowReadyToCompareProducts]
Use Case

3.7.25

Show recently compared products

Primary Actor: Customer Precondition: None Trigger: The customer wants to visualize the products on his recently compared list. Main success scenario 1. The system shows the products in the customers recently compared list. [ShowRecentlyComparedProducts]
Use Case

3.7.26

Show recently viewed products

Primary Actor: Customer Precondition: None Trigger: The customer wants to visualize the products on his recently viewed list. Main success scenario 1. The system shows the products in the customers recently viewed list. [ShowRecentlyViewedProducts]
Use Case

3.7.27

Show compare

Primary Actor: Customer Precondition: There is at least one product in the customers ready to compare list Trigger: The customer wants to visualize the comparable attributes of products in his ready to compare list. 192

Main success scenario 1. The system shows the comparable attributes of products in the customers ready to compare list. [ShowCompare]
Use Case

3.7.28

Add a newsletter template

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a newsletter template Main success scenario 1. The store administrator provides the details of the new newsletter template. 2. The system validates that the data is correct. 3. The system saves the new newsletter template. [NewNewsletterTemplate] Extensions 2a.The store administrator wants to see a preview of the newsletter template. 2a1. The system displays a preview of the newsletter template. 2a2. The use case continues at step 2
Use Case

3.7.29

Edit a newsletter template

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a newsletter template Main success scenario 1. 2. 3. 4. The store administrator selects the newsletter template to be edited. The store administrator provides the new details of the newsletter template. The system validates that the data is correct. The system saves the changes. [EditNewsletterTemplate]

Use Case

3.7.30

Delete a newsletter template

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a newsletter template Main success scenario 1. The store administrator selects the newsletter template to be deleted. 2. The system asks the store administrator a conrmation 3. The store administrator conrms that he wants to delete the newsletter template 193

4. The system deletes the newsletter template and all the newsletters created with this template. [DeleteNewsletterTemplate] Extensions 2a.The store administrator doesnt want to delete the newsletter template 2a1. The use case ends
Use Case

3.7.31

Add a newsletter

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add a newsletter Main success scenario 1. The store administrator selects the newsletter template that will be used to create this template. 2. The store administrator provides the details of the new newsletter, including optionally redenitions of the details taken from the newsletter template. 3. The system validates that the data is correct. 4. The system saves the new newsletter. [NewNewsletter]
Use Case

3.7.32

Edit a newsletter

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to edit a newsletter Main success scenario 1. 2. 3. 4. The store administrator selects the newsletter to be edited. The store administrator provides the new details of the newsletter. The system validates that the data is correct. The system saves the changes. [EditNewsletter]

Use Case

3.7.33

Subscribe to the newsletter

Primary Actor: Customer Precondition: None Trigger: A customer wants to subscribe himself to the newsletter Main success scenario 1. The customer provides an email 2. The system subscribes the costumer to the newsletter of the current store view. [SignUpForNewsletter] Extensions 194

1a.The customer does not provide an email, but it is a registered customer. 1a1. The use case continues at step 2 1b.The customer does not provide an email and it is not a registered customer. 1b1. The system informs the customer that providing an email is mandatory. 1b2. The use case continues at step 1
Use Case

3.7.34

Unsubscribe from the newsletter

Primary Actor: Customer Precondition: The customer is not subscribed to the newsletter in the current store view Trigger: A customer wants to unsubscribe himself from the newsletter Main success scenario 1. The system unsubscribes the costumer from the newsletter in this store view. [SignDownFromNewsletter]
Use Case

3.7.35

Delete a newsletter subscription

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to delete a newsletter subscription. Main success scenario 1. The store administrator selects the subscription to delete. 2. The system deletes the newsletter subscription [DeleteNewsletterSubscription]
Use Case

3.7.36

Unsubscribe a newsletter subscription

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to unsubscribe a newsletter subscription. Main success scenario 1. The store administrator selects the subscription to delete. 2. The system changes the newsletter subscription status to disabled. [UnsubscribeNewsletterSubscription]
Use Case

3.7.37

Show shopping cart

Primary Actor: Customer Precondition: None Trigger: The customer wants to visualize the products in his shopping cart.

195

Main success scenario 1. The system shows the products in the costumers shopping cart and the quantity chosen for each item [ShowShoppingCart]
Use Case

3.7.38

Download a product

Primary Actor: Customer Precondition: The customer is logged in. The customer purchased the product. Download is enabled by the system. The download is not expired and the number of download has not been exceeded. Trigger: A customer wants to download an item of a downloadable product that he has purchased. Main success scenario 1. The customer selects the item to be downloaded [ProductDownload] 2. The system allows the customer downloading the downloadable item
Use Case

3.7.39

Show downloadable products of a customer

Primary Actor: Customer Precondition: None Trigger: The Customer wants to visualize the downloadable products that he has already purchased. Main success scenario 1. The system shows the downloadable products purchased by the Customer. [ShowDownloadableProductsOfCustomer]
Use Case

3.7.40

Tell to a friend

Primary Actor: Customer Precondition: Tell to a friend is enabled by the system. If the customer is not logged in, tell to a friend is also enabled for guests. The number of maximum sents allowed has not been exceeded in the current hour. Trigger: A customer wants to send information about a product to a friend with a comment by email Main success scenario 1. The customer selects the product to be sent 2. The customer provides his name, his friends name, his email, his friends email and the message about the product. 3. The system saves that the customer has used the "tell to a friend"feature. [TellToAFriendUsed]

196

4. The system sends the email with a link to the current product information.
Use Case

3.7.41

View product information

Primary Actor: Customer Precondition: The product is enabled in the current website. Trigger: A customer wants to see detailed information of a product Main success scenario 1. The customer selects a product 2. The system adds the product to the customers recently viewed products list [ProductViewed] 3. The system shows the detailled information about this product [ShowProductInfo]
Use Case

3.7.42

Search products

Primary Actor: Customer Precondition: None Trigger: A customer wants to search products by one or more keywords Main success scenario 1. The customer enters one or more keywords to search 2. The system shows the products that t the keywords. [ShowFoundProducts]
Use Case

3.7.43

Show the best purchased products

Primary Actor: Customer Precondition: None Trigger: The Customer enters to the system Main success scenario 1. The system shows the products in stock that have been purchased more times by the customers, ordered by the number of times purchased. [ShowBestPurchasedProducts]
Use Case

3.7.44

Reset the temporal information

Primary Actor: System Precondition: None Trigger: An hour has passed since the last time the use case has been applied. Main success scenario 197

1. The system resets to its initial values all the temporal information that should be erased after an hour. [ResetTemporalInfo]

198

3.8 Online catalog


Use Case

3.8.1

Place an order

Primary Actor: Customer Precondition: None Trigger: A customer wants to place and order. Main success scenario 1. At any time before step 11 the customer, may log in: [LogIn] 2. The system adds the contents of the anonymous shopping cart to the customer shopping cart. 3. The system displays the contents of the shopping cart. 4. The system calculates the applicable discounts to this shopping cart 5. The customer browses the product catalog [ShowProductInfo] [ProductViewed] 6. The customer selects a product to buy [AddProductToShoppingCart] 7. The system displays the contents of the shopping cart 8. The customer changes the contents of the shopping cart [UpdateShoppingCart] 9. The system updates the shopping cart 10. The system displays the contents of the updated shopping cart. The customer repeats steps from 3 to 1 as necessary to build his order. 11. The customer checks out the order 12. The system shows the default customers shipping address. 13. The customer accepts the shipping address. 14. The system shows the default customers billing address. 15. The customer accepts the billing address. 16. The system shows the available shipping methods with their cost 17. The customer selects the preferred shipping method 18. The system shows the available payment methods 19. The customer selects the preferred payment method 20. The system displays a summary of the order. 21. The customer conrms the order [OrderConrmation] 22. The system saves the order 23. The system sends an email to the customer with the information about the order. Extensions 1a.The customer is new 1a1. 5a.The customer wants to add a product from his wish list 5a1. The system displays the contents of the wish list 5a2. The use case continues at step 6 5b.The customer wants to add a product from his ready to compare list 5b1. The system displays the contents of the ready to compare list 5b2. The use case continues at step 6 199

5c.The customer wants to add a product from his recently viewed products list 5c1. The system displays the contents of the recently viewed products list 5c2. The use case continues at step 6 5d.The customer wants to add a product from his recently compared products list 5d1. The system displays the contents of the recently compared products list 5d2. The use case continues at step 6 8a.The customer wants to use a coupon code 8a1. The customer provides the coupon code. 8a2. The system checks that the coupon code is applicable. 8a3. The system applies the corresponding discount. [ApplyCouponCode] 8a4. The use case continues at step 9. 8a2a.The coupon code is not applicable for this shopping cart 8a2a1. The use case continues at step 9. 8b.The customer wants to estimate the shipping and tax costs of the products in the shopping cart 8b1. The customer provides the Country, Zone or Postal Area where it is located. 8b2. The system shows the tax amount associated and adds it to the total order cost 8b3. The system shows the available shipping methods with their cost. 8b4. The customer selects the preferred shipping method 8b5. The system shows the estimated shipping and orders total cost. [ShowShippingCost] 11a.The customer wants to Checkout with multiple Adresses 11a1. 11b.The customer is not yet logged in 11b1. The system asks the customer to log in himself 11b2. The customer logs in. [LogIn] 11b3. The use case continues at step 12 11b1a.The customer wants to check out the order without logging in (as guest) and the conguration allows it. 11b1a1. The customer checks out without logging in. 11b1a2. The use case continues at step 12 12a, 20b.The customer wants to change the shipping address. 12a1. The system shows the know adresses of the customer. 12a2. The customer selects a different shipping addres. 12a3. The system shows the selected address. 12a4. The customer continues with the checkout procedure at step 13 12a2a, 14a2a.The customer wants to dene a new address 12a2a1. The customer gives the new address: [NewCustomerAddress] 12a2a2. The system saves the adress. 12a2a3. The system shows the new address. 12a2a4. The customer continues with the checkout procedure at step 13 12b.All products in the shopping car are virtual or downloadable 12b1. The customer continues with the checkout procedure at step 13 13a.The customer wants to choose the same billing and shipping address 13a1. The customer continues with the checkout procedure at step 16 14a, 20b.The customer wants to change the billing address. 14a1. The system shows the know adresses of the customer. 14a2. The customer selects a different billing addres. 14a3. The system shows the selected address 14a4. The customer continues with the checkout procedure at step 16 16a.The customer wants to add a gift message 200

16a1. The customer enters the gift message information 16a2. The system saves the gift message [AddGiftMessage] 16a3. The customer continues with the checkout procedure at step 17 20a.The customer wants to change the contents of the shopping cart 20a1. The customer continues with the checkout procedure at step 3
Use Case

3.8.2

Checkout an order with multiple addresses

Primary Actor: Customer Precondition: The customers shopping cart is not empty Trigger: A customer wants to ship the orders products to multiple adresses Main success scenario 1. 2. 3. 4. 5. 6. 7. The customer selects the quantity of each product that will be shipped to each address. The system shows the available shipping methods. The customer chooses a shipping method for each address. The system shows the available payment methods and the default billing address The customer chooses a payment method for all addresses The system displays a summary of the order. The customer conrms the order [OrderConrmationWithMultipleCheckout] 8. The system saves an order for each shipping address. 9. For each shipping address, the system sends an email to the customer with the information about the order. Extensions 1a, 4a2a.The customer wants to dene a new address 1a1. The customer gives the new address: [NewCustomerAddress] 1a2. The system saves the adress. 1a3. The system shows the new address. 1a4. The customer continues with the checkout procedure at step 1 2a.The customer wants to add a gift message to any of the addresses 2a1. The customer enters the gift message information 2a2. The system saves the gift message 2a3. The customer continues with the checkout procedure at step 2 4a.The customer wants to change the billing address. 4a1. The system shows all the customers addresses 4a2. The customer chooses an address. 4a3. The customer returns to step 4 4a2a.The customer wants to edit an Address 4a2a1. 4a2a2. The customer returns to step 4 6a.The customer wants to change the quantity of each product that will be shipped to each address 6a1. The customer returns to step 1 6b.The customer wants to change one or more shipping methods 6b1. The customer returns to step 2 6c.The customer wants to change the billing address.

201

6c1. The customer returns to step 4 6d.The customer wants to change the payment method. 6d1. The customer returns to step 4
Use Case

3.8.3

Add an order

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to add an order for a registered customer Main success scenario 1. The store administrator selects the customer. 2. The store administrator selects the website where the order will be placed 3. The system creates the administration shopping cart that will be used to choose the purchased products [NewAdministrationShoppingCart] 4. The system shows the order settings (currency the order will be placed with, customer group, customer email and shipping and billing addresses) and the customers buying activity lists. [ShowPredenedOrderSettings] [ShowShoppingCart] [ShowWishList] [ShowReadyToCompareProducts] [ShowRecentlyComparedProducts] [ShowRecentlyViewedProducts] 5. The system shows the available payment methods and its associated cost 6. The store administrator selects a payment method 7. The system shows the available shipping methods and its associated cost 8. The store administrator selects a shipping method The store administrator repeats steps 4 - 8 until he is done. 9. The store administrator conrms the current order settings 10. The system saves the order [OrderConrmation] 11. The system deletes the administration shopping cart that has been used. [DeleteAdministrationShoppingCart] Extensions 1a.The store administrator wants to add an order for a customer that doesnt have an account in the system yet. 1a1. 2a.The customers account is not visible in the selected website 2a1. The system creates an account for the registered customer in the selected website [DuplicateAccount] 4a.The store administrator wants to add products to the order 4a1. The system shows all the available products 4a2. The store administrator selects the products he want to purchase, and denes its quantity. 4a3. The system updates the selected products to be purchased [AddProductToShoppingCart] 4a4. The use case continues at step 4 4b.The store administrator wants to change the currency the order will be placed with 4b1. The system displays the available currencies

202

4b2. The store administrator selects a currency 4b3. The system changes the orders currency [ChangeCurrencyOfAdministrationShoppingCart] 4b4. The use case continues at step 4 4c.The store administrator wants to change the address details 4c1. The store administrator provides the new address details. 4c2. The system changes the new address details of the order. 4c3. The use case continues at step 4 4c1a.The store administrator wants to use a saved customers address 4c1a1. The system shows the customers addresses 4c1a2. The store administrator selects an address 4c1a3. The system changes the new address details of the order. 4c1a4. The use case continues at step 4 4d.The store administrator wants to change the customers group and email 4d1. The store administrator provides the new customers group and email. 4d2. The system updates the changes. [ChangeEMailAndGroupOfAdministrationShoppingCart] 4d3. The use case continues at step 4 4e.The store administrator wants to apply a shopping cart rule that works with coupon code 4e1. The store administrator provides the coupon code. 4e2. The system applies the shopping cart rule. [ApplyCouponCode] 4e3. The use case continues at step 4 4e2a.The coupon code does not match with any applicable rule 4e2a1. The system informs the store administrator that coupon code does not match 4e2a2. The use case continues at step 4 4f.The store administrator wants to add to the order a product that appears in the customers buying activity lists. 4f1. The store administrator selects the product 4f2. The system updates the changes [AddProductToShoppingCart] 4f3. The use case continues at step 4 4g.The store administrator wants to add a gift message for an item or the entire order 4g1. The store administrator selects an item or the whole order. 4g2. The store administrator provides the gift messsages details. 4g3. The system saves the changes. [AddGiftMessage] [AddGiftMessageToItem] 4g4. The use case continues at step 4 4h.The store administrator wants to add a comment to the order 4h1. The store administrator provides the comments details. 4h2. The system saves the changes. 4h3. The use case continues at step 4 10a.The order has no products added, no payment or shipping method selected or missing address and customer information. 10a1. The system shows to the customer the information that is missing. 10a2. The use case continues at step 4 10b.The store administrator wants to save the billing or shipping address in the address book 10b1. The system saves the new address [NewCustomerAddress] 10b2. The system saves the order [OrderConrmation]

203

Use Case

3.8.4

Cancel an order

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to cancel an order Main success scenario 1. 2. 3. 4. The store administrator selects the order to be cancelled. The system asks the store administrator a conrmation The store administrator conrms that he wants to cancel the order. The system sets the order status to cancelled. [CancelOrder]

Extensions 2a.The store administrator doesnt want to cancel the order. 2a1. The use case ends
Use Case

3.8.5

Hold an order

Primary Actor: Store Administrator Precondition: The order is not already hold. Trigger: The store administrator wants to put an order on hold. Main success scenario 1. 2. 3. 4. The store administrator selects the order to be on hold. The system asks the store administrator a conrmation The store administrator conrms that he wants to put the order on hold. The system sets the order status to hold. [HoldOrder]

Extensions 2a.The store administrator doesnt want to puth the order on hold. 2a1. The use case ends
Use Case

3.8.6

Unhold an order

Primary Actor: Store Administrator Precondition: The order is not already unhold. Trigger: The store administrator wants to release an order from holding status. Main success scenario 1. 2. 3. 4. The store administrator selects the order to be released from holding status. The system asks the store administrator a conrmation The store administrator conrms that he wants to release an order from holding status. The system sets the order status to its corresponding status. [UnholdOrder] 204

Extensions 2a.The store administrator doesnt want to release an order from holding status. 2a1. The use case ends
Use Case

3.8.7

Reorder

Primary Actor: Customer, Store Administrator Precondition: An order is already placed by the customer Trigger: A customer or the store administrator wants to reorder the items purchased in a previous order. Main success scenario 1. The customer or store administrator selects the order to be reordered. 2. The system adds to the customer shopping cart all the products in the selected order [Reorder] 3. The customer starts a checkout procedure Extensions 2a.The primary actor is the store administrator 2a1. The use case continues at step 3
Use Case

3.8.8

Add a gift message to a placed order

Primary Actor: Store Administrator Precondition: At least one order is placed in the system Trigger: The customer asks the store administrator to add a gift message to an entire order or to a order line. Main success scenario 1. The store administrator selects the order or the order line. 2. The store administrator provides the information about the gift message. 3. The system saves the gift message. [AddGiftMessageToExistingOrder]
Use Case

3.8.9

Print an Order

Primary Actor: Customer Precondition: The order is placed. Trigger: A customer wants to print a summary of an order. Main success scenario 1. The customer selects the order to be printed 2. The system allows the customer printing the order summary

205

Use Case

3.8.10

Send order information by email

Primary Actor: Store Administrator Precondition: At least one order is placed in the system Trigger: The store administrator wants to send and email to a customer with the details of an order he has purchased. Main success scenario 1. 2. 3. 4. The store administrator selects the order. The system asks the store administrator a conrmation The store administrator conrms that he wants to send the email. The system sends an email to the customer with the order details.

Extensions 2a.The store administrator doesnt want to send the email. 2a1. The use case ends
Use Case

3.8.11

Show previous orders of a customer

Primary Actor: Precondition: The customer is logged in Trigger: The Customer wants to visualize his orders Main success scenario 1. The system shows the previous orders made by the customer [ShowOrdersOfCustomer]
Use Case

3.8.12

Add an invoice

Primary Actor: Store Administrator Precondition: At least one order is placed in the system, with not all products invoiced. Trigger: The store administrator wants to generate an invoice for a saved order. Main success scenario 1. 2. 3. 4. The store administrator selects the order The system shows the information about the invoice it is going to create The store administrator conrms he wants to create the invoice. The system creates the invoice [AddInvoice]

Extensions 3a.The store administrator wants to change the quantity invoiced for each product 3a1. The store administrator denes the quantity he wants to invoice for each product. 3a2. The system validates that the data is correct. 3a3. The use case continues at step 2 3b.The store administrator wants to add a comment to the invoice 206

3b1. The store administrator provides the comment 3b2. The use case continues at step 2 4a.The store administrator wants to send an email conrmation to the customer 4a1. The system sends an email conrmation to the customers address. 4a2. The system creates the invoice [AddInvoice] 4a3. The use case ends. 4b.The store administrator wants to create a shipment with the same products of the invoice 4b1. The system creates both the shipment and the invoice [AddInvoice] [AddShipment] 4b2. The use case ends. 4b1a.The store administrator wants to add a tracking number to the shipment 4b1a1. The store administrator provides the tracking number details 4b1a2. The use case continues at step 1
Use Case

3.8.13

Register an invoice payment

Primary Actor: Store Administrator Precondition: At least one pending invoice is placed in the system. Trigger: The store administrator wants to register the payment of a saved invoice. Main success scenario 1. The store administrator selects the invoice to be paid. 2. The system registers that the payment has been made. [PayInvoice]
Use Case

3.8.14

Cancel an invoice

Primary Actor: Store Administrator Precondition: At least one not cancelled invoice is placed in the system. Trigger: The store administrator wants to cancel an invoice. Main success scenario 1. The store administrator selects the invoice. 2. The system cancels the invoice. [CancelInvoice]
Use Case

3.8.15

Add a shipment

Primary Actor: Store Administrator Precondition: At least one order is placed in the system, with not all products shipped. Trigger: The store administrator wants to generate a refund for a saved order. Main success scenario 1. The store administrator selects the order 207

2. The system shows the information about the shipment it is going to create 3. The store administrator conrms he wants to create the shipment. 4. The system creates the shipment [AddShipment] Extensions 3a.The store administrator wants to change the quantity shipped for each product 3a1. The store administrator denes the quantity he wants to ship for each product. 3a2. The system validates that the data is correct. 3a3. The use case continues at step 2 3b.The store administrator wants to add a tracking number to the shipment 3b1. The store administrator provides the tracking number details 3b2. The use case continues at step 2 3c.The store administrator wants to add a comment to the shipment 3c1. The store administrator provides the comment 3c2. The use case continues at step 2 4a.The store administrator wants to send an email conrmation to the customer 4a1. The system sends an email conrmation to the customers address. 4a2. The system creates the shipment [AddShipment] 4a3. The use case ends.
Use Case

3.8.16

Add a refund

Primary Actor: Store Administrator Precondition: At least one order is placed in the system, with at least one product invoiced. Trigger: The store administrator wants to generate a refund for a saved order. Main success scenario 1. 2. 3. 4. The store administrator selects the order The system shows the information about the refund it is going to create The store administrator conrms he wants to create the refund. The system creates the refund [AddRefund]

Extensions 3a.The store administrator wants to change the quantity refunded for each product 3a1. The store administrator denes the quantity he wants to refund for each product. 3a2. The system validates that the data is correct. 3a3. The use case continues at step 2 3b.The store administrator wants to add a comment to the refund 3b1. The store administrator provides the comment 3b2. The use case continues at step 2 4a.The store administrator wants to send an email conrmation to the customer 4a1. The system sends an email conrmation to the customers address. 4a2. The system creates the refund [AddRefund] 4a3. The use case ends.

208

Use Case

3.8.17

Cancel a refund

Primary Actor: Store Administrator Precondition: At least one non cancelled refund is placed in the system. Trigger: The store administrator wants to cancel a refund. Main success scenario 1. The store administrator selects the refund. 2. The system cancels the refund. [CancelRefund]
Use Case

3.8.18

Add a comment to an order, invoice, shipment or refund.

Primary Actor: Store Administrator Precondition: At least one invoice is placed in the system Trigger: The store administrator wants to add a comment to a saved order, invoice, shipment or refund. Main success scenario 1. 2. 3. 4. The store administrator selects the order, invoice, shipment or refund The system shows the information about the order, invoice, shipment or refund. The store administrator provides the comment The system saves the comment. [AddComment]

Extensions 3a.The store administrator wants to send an email notication to the customer 3a1. The system sends an email conrmation to the customers address. 3a2. The use case continues at step 1.

209

3.9 Store Reports


Use Case

3.9.1

Show the sales report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the sales in the system. Main success scenario 1. The store administrator provides the details to delimit the orders that will appear in the report, including the time period and scope. 2. The system shows the orders that meet the provided details. [ShowSalesReport]
Use Case

3.9.2

Show the tax report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the tax information of the system. Main success scenario 1. The store administrator provides the details to delimit the tax information that will appear in the report, including the time period and scope. 2. The system shows the tax information that meet the provided details. [ShowTaxInformationReport]
Use Case

3.9.3

Show the shipping report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the shipping information of the system. Main success scenario 1. The store administrator provides the details to delimit the shipping information that will appear in the report, including the time period and scope. 2. The system shows the shipping information that meet the provided details. [ShowShippingInformationReport]
Use Case

3.9.4

Show the invoices report


210

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the invoices in the system. Main success scenario 1. The store administrator provides the details to delimit the invoices that will appear in the report, including the time period and scope. 2. The system shows the invoices that meet the provided details. [ShowInvoicesReport]
Use Case

3.9.5

Show the refunds report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the refunds in the system. Main success scenario 1. The store administrator provides the details to delimit the refunds that will appear in the report, including the time period and scope. 2. The system shows the refunds that meet the provided details. [ShowRefundsReport]
Use Case

3.9.6

Show the coupon codes report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the coupon codes used in the system. Main success scenario 1. The store administrator provides the details to delimit the coupon codes that will appear in the report, including the time period and scope. 2. The system shows the coupon codes that meet the provided details and the orders where it have been used. [ShowCouponCodeReport]
Use Case

3.9.7

Show the products in carts report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize the products that appear in any shopping cart in the system. Main success scenario 1. The system shows the products that appear in any shopping cart in the system.

211

[ShowProductsInCartsReport] Extensions 1a.The store administrator wants to visualize the information for only a restricted scope 1a1. The system displays the available scopes 1a2. The system administrator selects a scope 1a3. The use case continues at step 1
Use Case

3.9.8

Show the abandoned carts report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize the carts of customers who added products to their shopping cart and then logged out. Main success scenario 1. The system shows he carts of customers who added products to their shopping cart and then logged out. [ShowAbandonedCartsReport] Extensions 1a.The store administrator wants to visualize the information for only a restricted scope 1a1. The system displays the available scopes 1a2. The system administrator selects a scope 1a3. The use case continues at step 1
Use Case

3.9.9

Show the bestseller products report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the bestseller products in the system. Main success scenario 1. The store administrator provides the time period and scope to delimit the besteller products that will appear in the report. 2. The system shows the best seller products in the system. [ShowBestsellersReport]
Use Case

3.9.10

Show the ordered products report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of all the ordered products in the system.

212

Main success scenario 1. The store administrator provides the time period and scope to delimit the besteller products that will appear in the report. 2. The system shows the ordered products products in the system. [ShowOrderedProductsReport]
Use Case

3.9.11

Show the most viewed products report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the most viewed products in the system. Main success scenario 1. The store administrator provides the time period and scope to delimit the most viewed products that will appear in the report. 2. The system shows the most viewed products in the system. [ShowMostViewedProductsReport]
Use Case

3.9.12

Show the stock of products report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the stock properties of the products in the system. Main success scenario 1. The store administrator provides the scope to delimit the products that will appear in the report. 2. The system shows the products in the system, ordered by its remaining quantity in stock. [ShowStockOfProductsReport]
Use Case

3.9.13

Show the downloads report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the downloads the customers have made in the system. Main success scenario 1. The store administrator provides the scope to delimit the downloads that will appear in the report. 2. The system shows the downloads the customers have made in the system. [ShowDownloadsReport]

213

Use Case

3.9.14

Show the new customer accounts report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the customer accounts that have been created in the system. Main success scenario 1. The store administrator provides the time period and scope to delimit the accounts that will appear in the report. 2. The system shows the customer accounts that have been created in the system.. [ShowNewCustomerAccountsReport]
Use Case

3.9.15

Show the customers by orders total report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the orders that each customer has placed, ordering customers by the total amount of its orders. Main success scenario 1. The store administrator provides the time period and scope to delimit the orders that will appear in the report. 2. The system shows the orders that each customer has placed, ordering customers by the total amount of its orders [ShowCustomersByOrdersTotalReport]
Use Case

3.9.16

Show the customers by number of orders report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the orders that each customer has placed, ordering customers by the number of orders they have placed. Main success scenario 1. The store administrator provides the time period and scope to delimit the orders that will appear in the report. 2. The system shows the orders that each customer has placed, ordering customers by the number of orders they have placed [ShowCustomersByNumberOfOrdersReport]
Use Case

3.9.17

Show the customer reviews report

Primary Actor: Store Administrator

214

Precondition: None Trigger: The store administrator wants to visualize a summary of the registered customers that have placed a review. Main success scenario 1. The system shows the customers that have placed a review and the number of total reviews that they have placed. [ShowCustomerReviewsReport]
Use Case

3.9.18

Show the product reviews report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the products that have received a review. Main success scenario 1. The system shows the products that have received one or more reviews. [ShowProductsReviewsReport]
Use Case

3.9.19

Show the tags by customer report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the customers who have submitted approved tags. Main success scenario 1. The system shows the customers who have submitted approved tags, and the number of approved tags they have submitted. [ShowTagsByCustomerReport]
Use Case

3.9.20

Show the tags by product report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of the products for which tags have been submitted. Main success scenario 1. The system shows the products for which tags have been submitted, and the number of approved tags. [ShowTagsByProductReport]

215

Use Case

3.9.21

Show the popular tags report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of all the approved tags in the system, ordered by the times it have been used. Main success scenario 1. The store administrator provides the scope to delimit the tags that will appear in the report. 2. The system shows all the approved tags in the system, ordered by the times it have been used. [ShowPopularTagsReport]
Use Case

3.9.22

Show the search terms report

Primary Actor: Store Administrator Precondition: None Trigger: The store administrator wants to visualize a summary of all the search terms used by customers. Main success scenario 1. The system shows all the search terms used by customers and the number of results that displayed the last time the search term was used. [ShowPopularTagsReport]

216

Behavioral Schema. Events Specication


In this chapter we develop the second part of the behavioral schema of the Magento information system: the specication of the Events dened in chapter 3. Section 4.1 denes the scope of the events elicitation, while section 4.2 describes the way the schema is presented. Section 4.3 presents an overview of the described Events, which are detailed in the remaining sections.

4.1 Scope
Events specication assumes that a set of events can be implicitly dened without explicitly specifying them. The whole schema and information base is assumed to be visible to the actors that interact with the system. Therefore, we assume that Queries, which only retrieve information from the IB, can be infered by its denition. Secondly, for each entity type three basic Events1 are assumed to exist: New, Edit and Delete events. They are known as Structural Events (see ?). In this chapter, they will be specied only if their effect or initial integrity constraints are relevant. For the remaining events, the following behaviour is assumed: New: creates a new object as an instance of the class specied in the events name. The event class has the same attributes and relationship types as the created objects class, so its values are copied from one object to another. Edit: replaces the values of an existing object. As New, event and edited classes have the same attributes and relationship types. A relationship is also dened between the two classes, to identify the existing object whose values will be replaced. Delete: deletes an object. If other objects are related to it with a multiplicity of 1, it may be deleted too. Some entities in the schema mantain information about the systems conguration. In those cases, no New or Delete Structural Event is dened. They are assumed to have the same behaviour as Edit Structural Events, excepting that the event can not replace the relationship
1 In permanent entities, no Delete Event can be dened. In constant entities, there cant be New or Delete Events dened.

217

with an store view or a website (it represents the scope where this conguration is applied). Thirdly, events specication only concerns about Simple Products. Thus, the following events are specied by supposing that the related product is simple:
I

NewProduct EditProduct AddProductToShoppingCart UpdateShoppingCart OrderConrmation

Other events that concern specically on Non-Simple Products are listed but not specied. A second iteration on the current project work should extend this scope (see section ??).

4.2 Schema presentation


First of all, we describe a complete list of the events, detailing those which are specied or only listed, and the Use Case group they belong to. In the next sections, the following information is given for each specied event:
I

Event Specication: following the approach presented in ?, events are modelized as entity types. Its attributes and relationship types (and those inherited from other events through generalization/specialization) represent the information needed for its execution. Initial Integrity Constraints: used as preconditions, they specify in OCL the state of the information base in which the event can be instantiated. Effect: all events use an effect operation, whose OCL postconditions dene the changes made made in the information base when the event occurs.

Events specication is organized in the same six groups as Use Cases, described in sections 2.3 and 3.2. Event Specication sections dene textually the events attributes and relationships. We use here an example to show the way they are described. First, we show the way it will be described by a classic UML Diagram.

218

In the following sections, this event would be textually specied as follows:


Attributes attribute2 : Type2 [multiplicity4] Relationships role2 : Class2 [multiplicity2] Generalizations Attributes inherited from AbstractEvent1 attribute1 : Type1 [multiplicity3] Relationships inherited from AbstractEvent1 role1 : Class1 [multiplicity1]

The correspondance between textual and visual specications can be easily established. Note that the multiplicity of an event role in all its relationships is assumed to be [*].

4.3 Events Overview


First of all, we present a summary of all the events specied in the use case specication. As some events are not specied (see scope restrictions in section 4.1), the criteria for not specifying them is listed below the event name. The specied events are highlighted in bold.

Store Conguration
NewWebsite. This event is a non-specied Structural Event. EditWebsite. This event is a non-specied Structural Event. DeleteWebsite. This event is a non-specied Structural Event. SetDefaultWebsite NewStore. This event is a non-specied Structural Event. EditStore. This event is a non-specied Structural Event. DeleteStore. This event is a non-specied Structural Event. SetDefaultStoreOfWebsite NewStoreView. This event is a non-specied Structural Event. EditStoreView. This event is a non-specied Structural Event. DeleteStoreView. This event is a non-specied Structural Event. SetDefaultStoreViewOfStore SetDefaultLanguage ChangeCatalogConguration. This event changes system conguration parameters. ChangeStockConguration. This event changes system conguration parameters. ChangeWishListConguration. This event changes system conguration parameters. ChangeSalesConguration. This event changes system conguration parameters. ChangeCustomerConguration. This event changes system conguration parameters. ChangeTaxConguration. This event changes system conguration parameters. ChangeShippingConguration. This event changes system conguration parameters. ChangeTellToAFriendConguration. This event changes system conguration parameters. ChangeCurrencyConguration. This event changes system conguration parameters.

219

ChangeEnabledCurrencies. This event changes system conguration parameters. UpdateCurrencyValue. This event changes system conguration parameters. ChangeGeographicalConguration. This event changes system conguration parameters. EditShippingMethods. This event changes system conguration parameters. EditPaymentMethods. This event changes system conguration parameters. NewCustomerTaxClass. This event is a non-specied Structural Event. EditCustomerTaxClass. This event is a non-specied Structural Event. DeleteCustomerTaxClass. This event is a non-specied Structural Event. NewProductTaxClass. This event is a non-specied Structural Event. EditProductTaxClass. This event is a non-specied Structural Event. DeleteProductTaxClass. This event is a non-specied Structural Event. NewTaxRate. This event is a non-specied Structural Event. EditTaxRate. This event is a non-specied Structural Event. DeleteTaxRate. This event is a non-specied Structural Event. NewTaxRule. This event is a non-specied Structural Event. EditTaxRule. This event is a non-specied Structural Event. DeleteTaxRule. This event is a non-specied Structural Event.

Customers
CreateCustomer PasswordChange EditCustomerDetails NewCustomerAddress DeleteCustomerAddress DefaultDeliveryAddressChange DefaultBillingAddressChange EditCustomerAddress EditCustomer. This event is a non-specied Structural Event. DeleteCustomer. This event is a non-specied Structural Event. ShowAccountInformation. This event is a query. ShowAddresses. This event is a query. NewCustomerGroup. This event is a non-specied Structural Event. EditCustomerGroup. This event is a non-specied Structural Event. DeleteCustomerGroup. This event is a non-specied Structural Event. NewAdministrator. This event is a non-specied Structural Event. EditAdministrator. This event is a non-specied Structural Event. DeleteAdministrator. This event is a non-specied Structural Event. NewRole. This event is a non-specied Structural Event. EditRole. This event is a non-specied Structural Event. DeleteRole. This event is a non-specied Structural Event. LogIn RestorePreviousShoppingCart RestorePreviousProductLists

220

LogOut SaveCurrentProductLists NewSession DeleteSession SetCurrentWebsite SetCurrentStore SetCurrentStoreView SetCurrentCurrency

Store Administration
ShowProductPropertiesAndAbleToRateAttributes. This event is a query. NewProduct EditProduct DeleteProduct NewCategory. This event is a non-specied Structural Event. EditCategory. This event is a non-specied Structural Event. MoveCategory DeleteCategory. This event is a non-specied Structural Event. ShowAttributeProperties. This event is a query. NewAttribute EditAttribute DeleteAttribute NewAttributeSet. This event is a non-specied Structural Event. EditAttributeSet. This event is a non-specied Structural Event. DeleteAttributeSet. This event is a non-specied Structural Event. NewTierPrice. This event is a non-specied Structural Event. EditTierPrice. This event is a non-specied Structural Event. DeleteTierPrice. This event is a non-specied Structural Event. NewCatalogPriceRule. This event is a non-specied Structural Event. EditCatalogPriceRule. This event is a non-specied Structural Event. ApplyCatalogPriceRule. This event . DeleteCatalogPriceRule. This event is a non-specied Structural Event. ApplyAllCatalogPriceRules. This event . NewShoppingCartPriceRule. This event is a non-specied Structural Event. EditShoppingCartPriceRule. This event is a non-specied Structural Event. DeleteShoppingCartPriceRule. This event is a non-specied Structural Event.

Additional Activities
NewTag. This event is a non-specied Structural Event. EditTag. This event is a non-specied Structural Event. DeleteTag. This event is a non-specied Structural Event. ShowTagsOfCustomer. This event is a query. ShowPopularTags. This event is a query.

221

ShowAllTags. This event is a query. NewReview NewAdministratorReview EditReview. This event is a non-specied Structural Event. DeleteReview. This event is a non-specied Structural Event. NewProperty. This event is a non-specied Structural Event. EditProperty. This event is a non-specied Structural Event. DeleteProperty. This event is a non-specied Structural Event. ShowReviewsOfProduct. This event is a query. ShowReviewsOfCustomer. This event is a query. AddProductToWishlist AddCommentToWishlistItem RemoveCommentFromWishlistItem RemoveProductFromWishlist AddProductToCompareList RemoveProductFromCompareList SingUpForPriceAlert SingUpForStockAlert ShowWishList. This event is a query. ShowReadyToCompareProducts. This event is a query. ShowRecentlyComparedProducts. This event is a query. ShowRecentlyViewedProducts. This event is a query. ShowCompare. This event is a query. NewNewsletterTemplate. This event is a non-specied Structural Event. EditNewsletterTemplate. This event is a non-specied Structural Event. DeleteNewsletterTemplate. This event is a non-specied Structural Event. NewNewsletter. This event is a non-specied Structural Event. EditNewsletter. This event is a non-specied Structural Event. SignUpForNewsletter SignDownFromNewsletter DeleteNewsletterSubscription. This event is a non-specied Structural Event. UnsubscribeNewsletterSubscription. This event . ShowShoppingCart. This event is a query. ProductDownload. This event concerns specically on Non-Simple Products. ShowDownloadableProductsOfCustomer. This event concerns specically on Non-Simple Products. TellToAFriendUsed ProductViewed ResetTemporalInfo

Online catalog
ShowProductInfo. This event is a query. ProductViewed

222

AddProductToShoppingCart UpdateShoppingCart ApplyCouponCode ShowShippingCost. This event is a query. OrderConrmation OrderConrmationWithMultipleCheckout. This event concerns specically on Non-Simple Products. DuplicateAccount NewAdministrationShoppingCart ShowPredenedOrderSettings. This event is a query. ShowShoppingCart. This event is a query. ShowWishList. This event is a query. ShowReadyToCompareProducts. This event is a query. ShowRecentlyComparedProducts. This event is a query. ShowRecentlyViewedProducts. This event is a query. ShowFoundProducts. This event is a query. ShowBestPurchasedProducts. This event is a query. AddProductToShoppingCart ChangeCurrencyOfAdministrationShoppingCart ChangeEMailAndGroupOfAdministrationShoppingCart ApplyCouponCode AddProductToShoppingCart AddGiftMessage AddGiftMessageToItem AddGiftMessageToExistingOrder. This event . OrderConrmation DeleteAdministrationShoppingCart CancelOrder HoldOrder UnholdOrder Reorder ShowOrdersOfCustomer. This event is a query. AddInvoice PayInvoice CancelInvoice AddShipment AddRefund CancelRefund AddComment

Store Reports
ShowSalesReport. This event is a query. ShowTaxInformationReport. This event is a query.

223

ShowShippingInformationReport. This event is a query. ShowInvoicesReport. This event is a query. ShowRefundsReport. This event is a query. ShowCouponCodeReport. This event is a query. ShowProductsInCartsReport. This event is a query. ShowAbandonedCartsReport. This event is a query. ShowBestsellersReport. This event is a query. ShowOrderedProductsReport. This event is a query. ShowMostViewedProductsReport. This event is a query. ShowStockOfProductsReport. This event is a query. ShowDownloadsReport. This event is a query. ShowNewCustomerAccountsReport. This event is a query. ShowCustomersByOrdersTotalReport. This event is a query. ShowCustomersByNumberOfOrdersReport. This event is a query. ShowCustomerReviewsReport. This event is a query. ShowProductsReviewsReport. This event is a query. ShowTagsByCustomerReport. This event is a query. ShowTagsByProductReport. This event is a query. ShowPopularTagsReport. This event is a query. ShowPopularTagsReport. This event is a query.

Several events can be modelised as specializations of an abstract event, as structural entities do (see section 1.2). The abstract events specied here do not dene initial integrity constraints or effect postconditions, but attributes and relationships that will be inherited by concrete events. Accordingly, they are not dened in any Use Case and represent any valid change on the IB. We present here the specication of those Abstract Events:

ScopeDenedEvent
Relationships editForWebsiteScope : Website [0..1] editForStoreViewScope : StoreView [0..1]

ExistingOrderEvent
Relationships order : Order [1]

ExistingCustomerEvent
Relationships customer : Customer [1]

224

ExistingAdministratorEvent
Relationships administrator : Administrator [1]

StoreViewPlacedEvent
Relationships storeView : StoreView [1]

ExistingAdministrationShoppingCartEvent
Relationships shoppingCart : AdministrationShoppingCart [1]

ExistingShoppingCartEvent
Relationships shoppingCart : ShoppingCart [1]

ExistingSessionEvent
Relationships session : Session [1]

ExistingCustomerSessionEvent
Relationships customerSession : CustomerSession [1]

ExistingWishListItemEvent
Relationships wishListItem : WishListItem [1]

ExistingProductEvent
Relationships product : Product [1]

225

4.4 Store Conguration

Event

4.4.1

SetDefaultWebsite

From use case: Select the default website

Event Specication
Relationships website : Website [1]

Effect
context SetDefaultWebsite::effect() post: System.allInstances->any(true).defaultWebsite = self.website

Event

4.4.2

SetDefaultStoreOfWebsite

From use case: Select the default store of a website

Event Specication
Relationships store : Store [1] website : Website [1]

Initial Integrity Constraints


context SetDefaultStoreOfWebsite :: storeBelongsToWebsite() : Boolean body: self.website.store->includes(self.store)

Effect
context SetDefaultStoreOfWebsite::effect() post: self.website.defaultStore = self.store

226

Event

4.4.3

SetDefaultStoreViewOfStore

From use case: Select the default store view of a store

Event Specication
Relationships storeView : StoreView [1] store : Store [1]

Initial Integrity Constraints


context SetDefaultStoreViewOfStore :: storeBelongsToWebsite() : Boolean body: self.store.storeView->includes(self.storeView)

Effect
context SetDefaultStoreViewOfStore::effect() post: self.store.defaultStoreView = self.storeView

Event

4.4.4

SetDefaultLanguage

From use case: Select the default language

Event Specication
Relationships language : Language [1] Generalizations Relationships inherited from ScopeDenedEvent editForWebsiteScope : Website [0..1] editForStoreViewScope : StoreView [0..1]

Initial Integrity Constraints


context SetDefaultLanguage :: notTwoScopesDened() : Boolean body: self.editForWebsiteScope.isEmpty() or self.editForStoreViewScope.isEmpty()

227

Effect
context SetDefaultLanguage::effect() post: if self.editForWebsiteScope.notEmpty() then self.editForWebsiteScope.store.storeView -> forAll(stv|stv.language = self.language) else if self.editForStoreViewScope.notEmpty() then self.editForStoreViewScope.language = self.language else StoreView.allInstances -> forAll(stv|stv.language = self.language) endif endif

228

4.5 Customers

Event

4.5.1

CreateCustomer

From use case: Create a Customer

Event Specication
Attributes eMail : EMail [1] rstName : String [1] lastName : String [1] password : String [1] passwordConrmation : String [1] namePrex : String [0..1] middleName : String [0..1] nameSufx : String [0..1] dateOfBirth : Date [0..1] taxVatNumber : String [0..1] Generalizations Relationships inherited from StoreViewPlacedEvent storeView : StoreView [1]

Initial Integrity Constraints


context CreateCustomer :: customerDoesNotExist() : Boolean body: not Customer.allInstances() -> exists (c | c.eMail = self.eMail and c.websiteWhereIsVisible -> includes ( self.storeView.store.website ) ) context CreateCustomer :: passwordCorrect() : Boolean body: self.password = self.passwordConrmation

Effect
context CreateCustomer::effect() post: c.oclIsNew() and c.oclIsTypeOf(Customer) and c.eMail = self.eMail and c.rstName = self.rstName and c.lastName = self.lastName and c.password = self.password and c.namePrex = self.namePrex and c.middleName = self.middleName and c.nameSufx = self.nameSufx and c.dateOfBirth = self.dateOfBirth and c.taxVatNumber = self.taxVatNumber and c.createdAt = Now() and c.storeViewWhereIsCreated = self.storeView and c.websiteWhereIsAssociated = self.storeView.store.website and

229

c.customerGroup = self.storeView.customerCongurationInStoreView.defaultCustomerGroup

Event

4.5.2

PasswordChange

From use case: Change password

Event Specication
Attributes oldPassword : String [1] newPassword : String [1] newPasswordConrmation : String [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context PasswordChange :: oldPasswordIsCorrect() : Boolean body: customer.password = self.oldPassword context PasswordChange :: passwordCorrect() : Boolean body: self.newPassword = self.newPasswordConrmation

Effect
context PasswordChange::effect() post: self.customer.password = self.newPassword

Event

4.5.3

EditCustomerDetails

From use case: Change customer details

Event Specication
Attributes newFirstName : String [1] newLastName : String [1] newEMail : EMail [1]

230

Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from StoreViewPlacedEvent storeView : StoreView [1]

Initial Integrity Constraints


context EditCustomerDetails :: customerDoesNotExist() : Boolean body: not Customer.allInstances() -> exists (c | c.eMail = self.newEMail and c.websiteWhereIsVisible -> includes ( self.storeView.store.website ) )

Effect
context EditCustomerDetails::effect() post: self.customer.rstName = self.newFirstName and self.customer.lastName = self.newLastName and self.customer.eMail = self.newEMail

Event

4.5.4

NewCustomerAddress

From use case: Administrate address book, Place an Order, Checkout with multiple addresses, Add an order

Event Specication
Attributes newFirstName : String [1] newMiddleName : String [0..1] newLastName : String [1] newNamePrex : String [0..1] newNameSufx : String [0..1] newCompany : String [0..1] newStreetAddress : String [1] newTelephone : String [1] newFax : String [0..1] Relationships country : Country [1] zone : Zone [0..1] municipality : Municipality [1] postalArea : PostalArea [0..1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context NewCustomerAddress :: hasACorrectZoneIfItIsNeeded() : Boolean

231

body: self.country.zone -> notEmpty() = (self.zone -> notEmpty() and self.country = self.zone.country) context NewCustomerAddress :: municipalityBelongsToCorrectZoneIfItIsNeeded() : Boolean body: self.municipality.country.zone -> notEmpty() = (self.municipality.zone -> notEmpty() and self.municipality.country = self.municipality.zone.country) context NewCustomerAddress :: hasAPostalAreaIfItIsNeeded() : Boolean body: self.country.postalCodeIsMandatory implies self.postalArea -> notEmpty() context NewCustomerAddress :: hasACorrectPostalArea() : Boolean body: self.municipality.postalArea -> includes( self.postalArea ) context NewCustomerAddress :: hasACorrectMunicipality() : Boolean body: self.country.municipality -> includes( self.municipality ) and self.zone -> notEmpty() implies self.zone.municipality -> includes ( self.municipality ) context NewCustomerAddress :: hasACorrectZone() : Boolean body: self.country.zone -> includes( self.zone )

Effect
context NewCustomerAddress::effect() post: Address.allInstances() -> exists(a| a.rstName = self.newFirstName and a.middleName = self.newMiddleName and a.lastName = self.newLastName and a.namePrex = self.newNamePrex and a.nameSufx = self.newNameSufx and a.company = self.newCompany and a.streetAddress = self.newStreetAddress and a.telephone = self.newTelephone and a.fax = self.newFax and a.country = self.country and a.zone = self.zone and a.municipality = self.municipality and a.postalArea = self.postalArea and self.customer.address -> includes(a))

Event

4.5.5

DeleteCustomerAddress

From use case: Administrate address book

Event Specication
Relationships

232

address : Address [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context DeleteCustomerAddress :: addressOfCustomer() : Boolean body: self.customer.address -> includes(self.address)

Effect
context DeleteCustomerAddress::effect() post: self.customer.address -> excludes(self.address)

Event

4.5.6

DefaultDeliveryAddressChange

From use case: Administrate address book

Event Specication
Relationships address : Address [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context DefaultDeliveryAddressChange :: addressOfCustomer() : Boolean body: self.customer.address -> includes(self.address)

Effect
context DefaultDeliveryAddressChange::effect() post: self.customer.defaultDelivery = self.address

233

Event

4.5.7

DefaultBillingAddressChange

From use case: Administrate address book

Event Specication
Relationships address : Address [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context DefaultBillingAddressChange :: addressOfCustomer() : Boolean body: self.customer.address -> includes(self.address)

Effect
context DefaultBillingAddressChange::effect() post: self.customer.defaultBilling = self.address

Event

4.5.8

EditCustomerAddress

From use case: Administrate address book

Event Specication
Attributes newAddress : Address [1] Relationships address : Address [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context EditCustomerAddress :: addressOfCustomer() : Boolean body:

234

self.customer.address -> includes(self.address) context EditCustomerAddress :: hasACorrectZoneIfItIsNeeded() : Boolean body: self.newAddress.country.zone -> notEmpty() implies (self.newAddress.zone -> notEmpty() and self.newAddress.country = self.newAddress.zone.country) context EditCustomerAddress :: hasAMunicipalityOfTheCorrectZoneIfItIsNeeded() : Boolean body: self.newAddress.municipality.country.zone -> notEmpty() implies (self.newAddress.municipality.zone -> notEmpty() and self.newAddress.municipality.country = self.newAddress.municipality.zone.country) context EditCustomerAddress :: hasAPostalAreaIfItIsNeeded() : Boolean body: self.newAddress.newAddress.country.postalCodeIsMandatory implies self.newAddress.postalArea -> notEmpty() context EditCustomerAddress :: hasACorrectPostalArea() : Boolean body: self.newAddress.municipality.postalArea -> includes( self.newAddress.postalArea ) context EditCustomerAddress :: hasACorrectMunicipality() : Boolean body: self.newAddress.country.municipality -> includes( self.newAddress.municipality ) and self.newAddress.zone -> notEmpty() implies self.newAddress.zone.municipality -> includes ( self.newAddress.municipality ) context EditCustomerAddress :: hasACorrectZone() : Boolean body: self.newAddress.country.zone -> includes( self.newAddress.zone )

Effect
context EditCustomerAddress::effect() post: self.customer.address -> excludes(self.address) and self.customer.address ->includes(self.newAddress)

Event

4.5.9

LogIn

From use case: Log In, Place an Order

Event Specication
Relationships anonymousSession : AnonymousSession [1] Generalizations

235

Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context LogIn :: CustomerIsNotLoggedIn() : Boolean body: self.customer.customerSession -> isEmpty() context LogIn :: CustomerIsVisibleInWebsite() : Boolean body: self.customer.websiteWhereIsVisible -> includes(self.anonymousSession.storeView.store.website)

Effect
context LogIn::effect() post: s.oclIsNew() and s.oclIsTypeOf(CustomerSession) and s.ipAddress = self.anonymousSession.ipAddress and s.createdAt = self.anonymousSession.createdAt and s.lastActivityAt = Now() and s.customer = self.customer and s.storeView = self.anonymousSession.storeView and if self.customer.lastCurrentCurreny.isDened() then s.currentCurrency = self.customer.lastCurrentCurrency else s.currentCurrency = self.anonymousSession.currentCurrency endif

Event

4.5.10

RestorePreviousShoppingCart

From use case: Log In

Event Specication
Relationships anonymousShoppingCart : AnonymousShoppingCart [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Effect
context RestorePreviousShoppingCart::effect() post createCustomerSC: self.customer@pre.customerShoppingCart.isEmpty() implies (sc.oclIsNew and sc.oclIsTypeOf(CustomerShoppingCart) and sc.customer = self.customer and sc.createdAt = Now() and sc.updatedAt = Now())

236

post updateCustomerSC: self.anonymousShoppingCart@pre.shoppingCartItem -> notEmpty() implies self.customer.customerShoppingCart.updatedAt = Now() post addProductsToCustomerSC: self.customer.customerShoppingCart.shoppingCartItem -> forAll ( i | (self.customer.customerShoppingCart@pre.shoppingCartItem -> includes(i) or self.anonymousShoppingCart@pre.shoppingCartItem -> includes(i)) and self.customer.customerShoppingCart.shoppingCartItem -> any( i2 | i.product=i2.product ).quantity = self.customer.customerShoppingCart@pre.shoppingCartItem -> any( i2 | i.product=i2.product ).quantity + self.anonymousShoppingCart@pre.shoppingCartItem -> any( i2 | i.product=i2.product ).quantity ) and self.customer.customerShoppingCart.couponCode = self.anonymousShoppingCart.couponCode post removeProductsFromAnonymousSC: self.anonymousShoppingCart.shoppingCartItem -> isEmpty()

Event

4.5.11

RestorePreviousProductLists

From use case: Log In

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context RestorePreviousProductLists :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty()

Effect
context RestorePreviousProductLists::effect() post: let infoCuSt: ActivityInfoOfCustomerInStoreView = self.customer.activityInfoOfCustomerInStoreView->any(ai|ai.storeViewWithInfoAbout=self.customer.customerSession.storeView) in let infoSeSt: ActivityInfoOfSessionInStoreView = self.customer.customerSession.activityInfoOfSessionInStoreView->any(ai|ai.storeViewWithInfoAbout=self.customer.customerSession.storeView) in let numProdsLeft : Integer = infoSeSt@pre.explicitRecentlyComparedProducts -> size() + infoCuSt.readyToCompareProducts -> size() - self.customer.customerSession.storeView.catalogCongurationInStoreView.numberOfRecentlyComparedProductsSaved in infoSeSt.explicitReadyToCompareProducts = infoSeSt@pre.explicitReadyToCompareProducts -> union ( infoCuSt.readyToCompareProducts ) and infoSeSt.explicitRecentlyComparedProducts = infoSeSt@pre.explicitRecentlyComparedProducts -> union (infoCuSt.recentlyComparedProducts.subOrderedSet(1, infoCuSt.recentlyComparedProducts->size() - numProdsLeft.max(0))) and

237

infoSeSt.explicitRecentlyViewedProducts = infoSeSt@pre.explicitRecentlyViewedProducts -> union (infoCuSt.recentlyViewedProducts.subOrderedSet(1, infoCuSt.recentlyViewedProducts->size() - numProdsLeft.max(0)))

post: let infoCuWe: ActivityInfoOfCustomerInWebsite = self.customer.activityInfoOfCustomerInWebsite->any(ai|ai.websiteWithInfoAbout=self.customer.customerSession.storeView.store.website) in let infoSeWe: ActivityInfoOfSessionInWebsite = self.customer.customerSession.activityInfoOfSessionInWebsite->any(ai|ai.websiteWithInfoAbout=self.customer.customerSession.storeView.store.website) in let numProdsLeft : Integer = infoSeWe@pre.explicitRecentlyComparedProducts -> size() + infoCuWe.readyToCompareProducts -> size() - self.customer.customerSession.storeView.catalogCongurationInStoreView.numberOfRecentlyComparedProductsSaved in infoSeWe.explicitReadyToCompareProducts = infoSeWe@pre.readyToCompareProducts -> union ( infoCuWe.readyToCompareProducts ) and infoSeWe.explicitRecentlyComparedProducts = infoSeWe@pre.explicitRecentlyComparedProducts -> union (infoCuWe.recentlyComparedProducts.subOrderedSet(1, infoCuWe.recentlyComparedProducts->size() - numProdsLeft.max(0))) and infoSeWe.explicitRecentlyViewedProducts = infoSeWe@pre.explicitRecentlyViewedProducts -> union (infoCuWe.recentlyViewedProducts.subOrderedSet(1, infoCuWe.recentlyViewedProducts->size() - numProdsLeft.max(0)))

Event

4.5.12

LogOut

From use case: Log Out

Event Specication

Generalizations Relationships inherited from ExistingCustomerSessionEvent customerSession : CustomerSession [1]

Effect
context LogOut::effect() post createAnonymousSession: s.oclIsNew() and s.oclIsTypeOf(AnonymousSession) and s.ipAddress = self.customerSession.ipAddress and s.createdAt = self.customerSession.createdAt and s.lastActivityAt = Now() and s.lastUrlVisited = self.anonymousSession.lastUrlVisited and s.storeView = self.customerSession.storeView and s.currentCurrency = self.customerSession.currentCurrency post saveCustomersCurrentCurrency: self.customerSession.customer.lastCurrentCurrency = self.customerSession.currentCurrency

238

Event

4.5.13

SaveCurrentProductLists

From use case: Log Out, Finish Session

Event Specication
Generalizations Relationships inherited from ExistingCustomerSessionEvent customerSession : CustomerSession [1]

Effect
context SaveCurrentProductLists::effect() post: let infoCuSt: ActivityInfoOfCustomerInStoreView = self.customer.activityInfoOfCustomerInStoreView->any(ai|ai.storeViewWithInfoAbout=self.customerSession.storeView) in let infoSeSt: ActivityInfoOfSessionInStoreView = self.customer.customerSession.activityInfoOfSessionInStoreView->any(ai|ai.storeViewWithInfoAbout=self.customerSession.storeView) in infoCuSt.readyToCompareProducts = infoSeSt@pre.explicitReadyToCompareProducts and infoCuSt.recentlyComparedProducts = infoSeSt@pre.explicitRecentlyComparedProducts and infoCuSt.recentlyViewedProducts = infoSeSt@pre.explicitRecentlyViewedProducts post: let infoCuWe: ActivityInfoOfCustomerInWebsite = self.customer.activityInfoOfCustomerInWebsite->any(ai|ai.websiteWithInfoAbout=self.customerSession.storeView.store.website) in let infoSeWe: ActivityInfoOfSessionInWebsite = self.customer.customerSession.activityInfoOfSessionInWebsite->any(ai|ai.websiteWithInfoAbout=self.customerSession.storeView.store.website) in infoCuWe.readyToCompareProducts = infoSeWe@pre.explicitReadyToCompareProducts and infoCuWe.recentlyComparedProducts = infoSeWe@pre.explicitRecentlyComparedProducts and infoCuWe.recentlyViewedProducts = infoSeWe@pre.explicitRecentlyViewedProducts

Event

4.5.14

NewSession

From use case: Open session

Event Specication

Attributes ipAddress : String [1] Relationships website : Website [1]

239

Initial Integrity Constraints


context NewSession :: ipAddressDoesNotExist() : Boolean body: not AnonymousSession.allInstances() -> exists(s|s.ipAddress=self.ipAddress)

Effect
context NewSession::effect() post: s.oclIsNew() and s.oclIsTypeOf(AnonymousSession) and s.ipAddress = self.ipAddress and s.createdAt = Now() and s.lastActivityAt = Now() and s.storeView = self.website.defaultStore.defaultStoreView and s.currentCurrency = s.storeView.currencyCongurationInStoreView.defaultCurrency and cart.oclIsNew() and cart.oclIsTypeOf(AnonymousShoppingCart) and s.oclAsType(AnonymousSession).anonymousShoppingCart = cart

Event

4.5.15

DeleteSession

From use case: Finish session

Event Specication
Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Effect
context DeleteSession::effect() post: not self.session@pre.oclIsKindOf(OclAny) post: self.session@pre.oclIsTypeOf(AnonymousSession) implies self.session@pre.anonymousShoppingCart -> isEmpty()

Event

4.5.16

SetCurrentWebsite

From use case: Change the current Website

Event Specication
240

Relationships website : Website [1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Effect
context SetCurrentWebsite::effect() post: self.session.storeView = self.website.defaultStore.defaultStoreView

Event

4.5.17

SetCurrentStore

From use case: Change the current Store

Event Specication
Relationships store : Store [1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Effect
context SetCurrentStore::effect() post: self.session.storeView = self.store.defaultStoreView

Event

4.5.18

SetCurrentStoreView

From use case: Change the current Store View

Event Specication
Relationships storeView : StoreView [1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

241

Effect
context SetCurrentStoreView::effect() post: self.session.storeView = self.storeView

Event

4.5.19

SetCurrentCurrency

From use case: Change the current Currency

Event Specication
Relationships currency : Currency [1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Initial Integrity Constraints


context SetCurrentCurrency :: currencyIsAllowed() : Boolean body: self.session.storeView.currencyCongurationInStoreView.allowedCurrency -> includes(self.currency)

Effect
context SetCurrentCurrency::effect() post: self.session.currentCurrency = self.currency

242

4.6 Store Administration

Event

4.6.1

NewProduct

From use case: Add a product

Event Specication
Attributes values : TupleType (a: Attribute, v: AttributeValue) [1..*] productType : ProductType [1] sku : String [1] name : String [1] netPrice : Money [1] weight : Decimal [0..1] status : Status [1] isNewFrom : Date [0..1] isNewUntil : Date [0..1] specialNetPrice : Money [0..1] specialNetPriceFrom : Date [0..1] specialNetPriceUntil : Date [0..1] description : String [0..1] shortDescription : String [0..1] metaDescription : String [0..1] metaKeyword : String [*] metaTitle : String [0..1] imageGalleryPath : String [0..1] baseImagePath : String [0..1] smallImagePath : String [0..1] thumbnailPath : String [0..1] urlKey : String [0..1] isAvailableForGoogleCheckout : Boolean [0..1] giftMessageAllowed : Boolean [0..1] visibleOnCatalog : Boolean [0..1] visibleOnSearch : Boolean [0..1] stockStatus : ProductStatus [1] quantity : PositiveInteger [0..1] qtyToBecomeOutOfStock : PositiveInteger [0..1] minQtyAllowedInShoppingCart : PositiveInteger [0..1] maxQtyAllowedInShoppingCart : PositiveInteger [0..1] notifyForQuantityBelow : PositiveInteger [0..1] backOrderPolicy : BackOrderPolicy [0..1] Relationships crossSellProduct : Product [*] upSellProduct : Product [*] relatedProduct : Product [*] website : Website [1..*] productTaxClass : ProductTaxClass [0..1] xedTaxRate : TaxRate [*] attributeSet : AttributeSet [1]

243

Initial Integrity Constraints


context NewProduct :: skuDoesNotExist() : Boolean body: not Product.allInstances() -> exists ( p | p.sku = self.sku ) context NewProduct :: attributesHaveOnlyOneValue() : Boolean body: self.values -> isUnique(attribute) context NewProduct :: attributeValuesHaveTheCorrectType() : Boolean body: self.values -> forAll ( v | (v.a.oclIsTypeOf ( TextualAttribute ) implies v.v.oclIsTypeOf ( TextualValue )) and (v.a.oclIsTypeOf ( PriceAttribute ) implies v.v.oclIsTypeOf ( PriceValue )) and (v.a.oclIsTypeOf ( DateAttribute ) implies v.v.oclIsTypeOf ( DateValue )) and (v.a.oclIsTypeOf ( BooleanAttribute ) implies v.v.oclIsTypeOf ( BooleanValue )) and (v.a.oclIsTypeOf ( IntegerAttribute ) implies v.v.oclIsTypeOf ( IntegerValue )) and (v.a.oclIsTypeOf ( DecimalAttribute ) implies v.v.oclIsTypeOf ( DecimalValue )) and (v.a.oclIsTypeOf ( ImageAttribute ) implies v.v.oclIsTypeOf ( ImageValue )) and (v.a.oclIsTypeOf ( SingleValuedEnumerationAttribute ) implies (v.v.oclIsTypeOf ( EnumerationValue ) and v.a.oclAsType(SingleValuedEnumerationAttribute).allowedValue>includes(v.v) )) and (v.a.oclIsTypeOf ( MultipleValuedEnumerationAttribute ) implies (v.v.oclIsTypeOf ( MultipleEnumerationValue ) and v.a.oclAsType(EnumerationValue).allowedValue>includesAll(v.v.oclAsType(MultipleValuedEnumerationAttribute).enumerationValue) )) ) context NewProduct :: onlyAbleToRateAttributesHaveValues() : Boolean body: let ableToRateAttributes : Set(Attribute) = self.attributeSet.attribute -> select(a|a.associatedProductType -> includes(self.productType)) in self.values->collect(a) -> forAll ( a | ableToRateAttributes -> includes(a) ) context NewProduct :: requiredAttributesHaveAValue() : Boolean body: let ableToRateAttributes : Set(Attribute) = self.attributeSet.attribute -> select(a|a.associatedProductType -> includes(self.productType)) in ableToRateAttributes -> forAll ( a | a.isRequired implies self.values->collect(a) -> includes(a) ) context NewProduct :: uniqueValuedAttributesHaveANonUsedValue() : Boolean body: self.values -> forAll ( v | v.a.hasUniqueValues implies not v.a.storeViewAttributeRating.attributeValue -> exists(val | val=v.v) ) context NewProduct :: onlyAbleToRatePropertiesHaveValues() : Boolean body: let conf : ProductPropertiesTypeAssociationConguration = ProductPropertiesTypeAssociationConguration.allInstances() -> any(true) in (self.name.isDened() implies conf.nameAssociatedToProductType->includes(self.productType)) and (self.netPrice.isDened() implies conf.netPriceAssociatedToProductType->includes(self.productType)) and (self.weight.isDened() implies conf.weightAssociatedToProductType->includes(self.productType)) and (self.status.isDened() implies conf.statusAssociatedToProductType->includes(self.productType)) and (self.isNewFrom.isDened() implies conf.isNewFromAssociatedToProductType->includes(self.productType)) and (self.isNewUntil.isDened() implies conf.isNewUntilAssociatedToProductType->includes(self.productType)) and (self.specialNetPrice.isDened() implies conf.specialNetPriceAssociatedToProductType->includes(self.productType)) and (self.specialNetPriceFrom.isDened() implies conf.specialNetPriceFromAssociatedToProductType->includes(self.productType)) and (self.specialNetPriceUntil.isDened() implies conf.specialNetPriceUntilAssociatedToProductType->includes(self.productType)) and (self.description.isDened() implies

244

conf.descriptionAssociatedToProductType->includes(self.productType)) and (self.shortDescription.isDened() implies conf.shortDescriptionAssociatedToProductType->includes(self.productType)) and (self.metaDescription.isDened() implies conf.metaDescriptionAssociatedToProductType->includes(self.productType)) and (self.metaKeyword -> forAll(k|k.isDened()) implies conf.metaKeywordAssociatedToProductType->includes(self.productType)) and (self.metaTitle.isDened() implies conf.metaTitleAssociatedToProductType->includes(self.productType)) and (self.imageGalleryPath.isDened() implies conf.imageGalleryPathAssociatedToProductType->includes(self.productType)) and (self.baseImagePath.isDened() implies conf.baseImagePathAssociatedToProductType->includes(self.productType)) and (self.smallImagePath.isDened() implies conf.smallImagePathAssociatedToProductType->includes(self.productType)) and (self.thumbnailPath.isDened() implies conf.thumbnailPathAssociatedToProductType->includes(self.productType)) and (self.urlKey.isDened() implies conf.urlKeyAssociatedToProductType->includes(self.productType)) and (self.isAvailableForGoogleCheckout.isDened() implies conf.isAvailableForGoogleCheckoutAssociatedToProductType->includes(self.productType)) and (self.giftMessageAllowed.isDened() implies conf.giftMessageAllowedAssociatedToProductType->includes(self.productType)) and (self.visibleOnCatalog.isDened() implies conf.visibleOnCatalogAssociatedToProductType->includes(self.productType)) and (self.visibleOnSearch.isDened() implies conf.visibleOnSearchAssociatedToProductType->includes(self.productType)) context NewProduct :: mandatoryPropertiesAreRated() : Boolean body: let confType : ProductPropertiesTypeAssociationConguration = ProductPropertiesTypeAssociationConguration.allInstances() -> any(true) in let confOblig : ProductPropertiesObligatorinessConguration = ProductPropertiesObligatorinessConguration.allInstances() -> any(true) in ((confOblig.isNewFromIsMandatory and confType.isNewFromAssociatedToProductType->includes(self.productType)) implies self.isNewFrom.isDened()) and ((confOblig.isNewUntilIsMandatory and confType.isNewUntilAssociatedToProductType->includes(self.productType)) implies self.isNewUntil.isDened()) and ((confOblig.specialNetPriceIsMandatory and confType.specialNetPriceAssociatedToProductType->includes(self.productType)) implies self.specialNetPrice.isDened()) and ((confOblig.specialNetPriceFromIsMandatory and confType.specialNetPriceFromAssociatedToProductType->includes(self.productType)) implies self.specialNetPriceFrom.isDened()) and ((confOblig.specialNetPriceUntilIsMandatory and confType.specialNetPriceUntilAssociatedToProductType->includes(self.productType)) implies self.specialNetPriceUntil.isDened()) and ((confOblig.descriptionIsMandatory and confType.descriptionAssociatedToProductType->includes(self.productType)) implies self.description.isDened()) and ((confOblig.shortDescriptionIsMandatory and confType.shortDescriptionAssociatedToProductType->includes(self.productType)) implies self.shortDescription.isDened()) and ((confOblig.metaDescriptionIsMandatory and confType.metaDescriptionAssociatedToProductType->includes(self.productType)) implies self.metaDescription.isDened()) and ((confOblig.metaKeywordIsMandatory and confType.metaKeywordAssociatedToProductType->includes(self.productType)) implies self.metaKeyword -> forAll(k|k.isDened())) and ((confOblig.metaTitleIsMandatory and confType.metaTitleAssociatedToProductType->includes(self.productType)) implies self.metaTitle.isDened()) and ((confOblig.imageGalleryPathIsMandatory and confType.imageGalleryPathAssociatedToProductType->includes(self.productType)) implies self.imageGalleryPath.isDened()) and ((confOblig.baseImagePathIsMandatory and confType.baseImagePathAssociatedToProductType->includes(self.productType)) implies self.baseImagePath.isDened()) and ((confOblig.smallImagePathIsMandatory and confType.smallImagePathAssociatedToProductType->includes(self.productType)) implies self.smallImagePath.isDened()) and ((confOblig.thumbnailPathIsMandatory and

245

confType.thumbnailPathAssociatedToProductType->includes(self.productType)) implies self.thumbnailPath.isDened()) and ((confOblig.urlKeyIsMandatory and confType.urlKeyAssociatedToProductType->includes(self.productType)) implies self.urlKey.isDened()) and ((confOblig.isAvailableForGoogleCheckoutIsMandatory and confType.isAvailableForGoogleCheckoutAssociatedToProductType->includes(self.productType)) implies self.isAvailableForGoogleCheckout.isDened()) and ((confOblig.giftMessageAllowedIsMandatory and confType.giftMessageAllowedAssociatedToProductType->includes(self.productType)) implies self.giftMessageAllowed.isDened()) and ((confOblig.visibleOnCatalogIsMandatory and confType.visibleOnCatalogAssociatedToProductType->includes(self.productType)) implies self.visibleOnCatalog.isDened()) and ((confOblig.visibleOnSearchIsMandatory and confType.visibleOnSearchAssociatedToProductType->includes(self.productType)) implies self.visibleOnSearch.isDened()) context NewProduct :: stockOptionsAreRatedOnlyForTheCorrectProductTypes() : Boolean body: ( self.productType=ProductType::Grouped or self.productType=ProductType::Congurable or self.productType=ProductType::Bundle ) implies ( self.quantity.isUndened() and self.qtyToBecomeOutOfStock.isUndened() and self.minQtyAllowedInShoppingCart.isUndened() and self.maxQtyAllowedInShoppingCart.isUndened() and self.notifyForQuantityBelow.isUndened()and self.backOrderPolicy.isUndened() )

Effect
context NewProduct::effect() post productIsCreated: p.oclIsNew() and p.oclIsKindOf(Product) and self.productType = ProductType::Simple implies p.oclIsTypeOf(SimpleProduct) and self.productType = ProductType::Grouped implies p.oclIsTypeOf(GroupedProduct) and self.productType = ProductType::Congurable implies p.oclIsTypeOf(CongurableProduct) and self.productType = ProductType::Virtual implies p.oclIsTypeOf(VirtualProduct) and self.productType = ProductType::Bundle implies p.oclIsTypeOf(BundleProduct) and self.productType = ProductType::Downloadable implies p.oclIsTypeOf(DownloadableProduct) and p.productTaxClass = self.productTaxClass and p.xedTaxRate = self.xedTaxRate and p.attributeSet = self.attributeSet and p.crossSellProduct = self.crossSellProduct and p.upSellProduct = self.upSellProduct and p.relatedProduct = self.relatedProduct and Website.allInstances() -> forAll ( w | piw.oclIsNew() and piw.oclIsTypeOf(ProductInWebsite) and piw.product = p and piw.website = w and piw.isAvailable = (self.website -> includes(w)) ) and StoreView.allInstances() -> forAll ( stw | pis.oclIsNew() and pis.oclIsTypeOf(ProductInStoreView) and pis.product = p and pis.storeView = stw ) and let ableToRateAttributes : Set(Attribute) = self.attributeSet.attribute -> select(a|a.associatedProductType -> includes(self.productType)) in ableToRateAttributes -> forAll ( a | gar.oclIsNew() and gar.oclIsTypeOf(GlobalAttributeRating) and gar.productOfGloballyRatedAttribute = p and gar.globallyRatedAttribute = a and Website.allInstances() -> forAll ( w | war.oclIsNew() and war.oclIsTypeOf(WebsiteAttributeRating) and war.websiteRatedProduct = p and war.websiteRatedAttribute = a and war.websiteWhereIsRated = w ) and StoreView.allInstances() -> forAll ( s | sar.oclIsNew() and sar.oclIsTypeOf(StoreViewAttributeRating) and

246

sar.storeViewRatedProduct = p and sar.storeViewRatedAttribute = a and sar.storeViewWhereIsRated = s )) post attributesAreRated: self.values -> forAll ( v | v.a.globalAttributeRating->any(gar|gar.productOfGloballyRatedAttribute=p).genericAttributeValue=v.v ) post propertiesAreRated: p.sku = self.sku and p.genericName = self.name and p.genericNetPrice = self.netPrice and p.genericWeight = self.weight and p.genericStatus = self.status and p.genericIsNewFrom = self.isNewFrom and p.genericIsNewUntil = self.isNewUntil and p.genericSpecialNetPrice = self.specialNetPrice and p.genericSpecialNetPriceFrom = self.specialNetPriceFrom and p.genericSpecialNetPriceUntil = self.specialNetPriceUntil and p.genericDescription = self.description and p.genericShortDescription = self.shortDescription and p.genericMetaDescription = self.metaDescription and p.genericMetaKeyword = self.metaKeyword and p.genericMetaTitle = self.metaTitle and p.genericImageGalleryPath = self.imageGalleryPath and p.genericBaseImagePath = self.baseImagePath and p.genericSmallImagePath = self.smallImagePath and p.genericThumbnailPath = self.thumbnailPath and p.genericUrlKey = self.urlKey and p.genericIsAvailableForGoogleCheckout = self.isAvailableForGoogleCheckout and p.genericIsGiftMessageAllowed = self.giftMessageAllowed and p.genericIsVisibleOnCatalog = self.visibleOnCatalog and p.genericIsVisibleOnSearch = self.visibleOnSearch and p.stockStatus = self.stockStatus and p.quantity = self.quantity and p.qtyToBecomeOutOfStock = self.qtyToBecomeOutOfStock and p.minQtyAllowedInShoppingCart = self.minQtyAllowedInShoppingCart and p.maxQtyAllowedInShoppingCart = self.maxQtyAllowedInShoppingCart and p.notifyForQuantityBelow = self.notifyForQuantityBelow and p.backOrderPolicy = self.backOrderPolicy

Event

4.6.2

EditProduct

From use case: Edit a product

Event Specication
Attributes values : TupleType (a: Attribute, v: AttributeValue) [1..*] sku : String [1] name : String [1] netPrice : Money [1] weight : Decimal [0..1] status : Status [1] isNewFrom : Date [0..1] isNewUntil : Date [0..1] specialNetPrice : Money [0..1] specialNetPriceFrom : Date [0..1] specialNetPriceUntil : Date [0..1] description : String [0..1] shortDescription : String [0..1]

247

metaDescription : String [0..1] metaKeyword : String [0..1] metaTitle : String [0..1] imageGalleryPath : String [0..1] baseImagePath : String [0..1] smallImagePath : String [0..1] thumbnailPath : String [0..1] urlKey : String [0..1] isAvailableForGoogleCheckout : Boolean [0..1] giftMessageAllowed : Boolean [0..1] visibleOnCatalog : Boolean [0..1] visibleOnSearch : Boolean [0..1] stockStatus : ProductStatus [1] quantity : PositiveInteger [0..1] qtyToBecomeOutOfStock : PositiveInteger [0..1] minQtyAllowedInShoppingCart : PositiveInteger [0..1] maxQtyAllowedInShoppingCart : PositiveInteger [0..1] notifyForQuantityBelow : PositiveInteger [0..1] backOrderPolicy : BackOrderPolicy [0..1] productType : ProductType [1] Relationships crossSellProduct : Product [*] upSellProduct : Product [*] relatedProduct : Product [*] website : Website [1..*] productTaxClass : ProductTaxClass [0..1] xedTaxRate : TaxRate [*] Generalizations Relationships inherited from ExistingProductEvent product : Product [1] Relationships inherited from ScopeDenedEvent editForWebsiteScope : Website [0..1] editForStoreViewScope : StoreView [0..1]

Initial Integrity Constraints


context EditProduct :: notTwoScopesDened() : Boolean body: self.editForWebsiteScope.isEmpty() or self.editForStoreViewScope.isEmpty() context EditProduct :: onlyAbleToRateAttributesHaveValues() : Boolean body: let ableToRateAttributes : Set(Attribute) = self.product.attributeSet.attribute -> select(a|a.associatedProductType -> includes(self.productType)) in self.values->collect(a) -> forAll ( a | ableToRateAttributes -> includes(a) ) context EditProduct :: requiredAttributesHaveAValue() : Boolean body: let ableToRateAttributes : Set(Attribute) = self.product.attributeSet.attribute -> select(a|a.associatedProductType -> includes(self.productType)) in ableToRateAttributes -> forAll ( a | a.isRequired implies self.values->collect(a) -> includes(a) ) context EditProduct :: attributesHaveOnlyOneValue() : Boolean body: self.values -> isUnique(attribute)

248

context EditProduct :: attributeValuesHaveTheCorrectType() : Boolean body: self.values -> forAll ( v | (v.a.oclIsTypeOf ( TextualAttribute ) implies v.v.oclIsTypeOf ( TextualValue )) and (v.a.oclIsTypeOf ( PriceAttribute ) implies v.v.oclIsTypeOf ( PriceValue )) and (v.a.oclIsTypeOf ( DateAttribute ) implies v.v.oclIsTypeOf ( DateValue )) and (v.a.oclIsTypeOf ( BooleanAttribute ) implies v.v.oclIsTypeOf ( BooleanValue )) and (v.a.oclIsTypeOf ( IntegerAttribute ) implies v.v.oclIsTypeOf ( IntegerValue )) and (v.a.oclIsTypeOf ( DecimalAttribute ) implies v.v.oclIsTypeOf ( DecimalValue )) and (v.a.oclIsTypeOf ( ImageAttribute ) implies v.v.oclIsTypeOf ( ImageValue )) and (v.a.oclIsTypeOf ( SingleValuedEnumerationAttribute ) implies (v.v.oclIsTypeOf ( EnumerationValue ) and v.a.oclAsType(SingleValuedEnumerationAttribute).allowedValue>includes(v.v) )) and (v.a.oclIsTypeOf ( MultipleValuedEnumerationAttribute ) implies (v.v.oclIsTypeOf ( MultipleEnumerationValue ) and v.a.oclAsType(EnumerationValue).allowedValue>includesAll(v.v.oclAsType(MultipleValuedEnumerationAttribute).enumerationValue) )) ) context EditProduct :: uniqueValuedAttributesHaveANonUsedValue() : Boolean body: self.values -> forAll ( v | v.a.hasUniqueValues implies not v.a.storeViewAttributeRating.attributeValue -> exists(val | val=v.v) ) context EditProduct :: onlyAbleToRatePropertiesHaveValues() : Boolean body: let conf : ProductPropertiesTypeAssociationConguration = ProductPropertiesTypeAssociationConguration.allInstances() -> any(true) in (self.name.isDened() implies conf.nameAssociatedToProductType->includes(self.productType)) and (self.netPrice.isDened() implies conf.netPriceAssociatedToProductType->includes(self.productType)) and (self.weight.isDened() implies conf.weightAssociatedToProductType->includes(self.productType)) and (self.status.isDened() implies conf.statusAssociatedToProductType->includes(self.productType)) and (self.isNewFrom.isDened() implies conf.isNewFromAssociatedToProductType->includes(self.productType)) and (self.isNewUntil.isDened() implies conf.isNewUntilAssociatedToProductType->includes(self.productType)) and (self.specialNetPrice.isDened() implies conf.specialNetPriceAssociatedToProductType->includes(self.productType)) and (self.specialNetPriceFrom.isDened() implies conf.specialNetPriceFromAssociatedToProductType->includes(self.productType)) and (self.specialNetPriceUntil.isDened() implies conf.specialNetPriceUntilAssociatedToProductType->includes(self.productType)) and (self.description.isDened() implies conf.descriptionAssociatedToProductType->includes(self.productType)) and (self.shortDescription.isDened() implies conf.shortDescriptionAssociatedToProductType->includes(self.productType)) and (self.metaDescription.isDened() implies conf.metaDescriptionAssociatedToProductType->includes(self.productType)) and (self.metaKeyword -> forAll(k|k.isDened()) implies conf.metaKeywordAssociatedToProductType->includes(self.productType)) and (self.metaTitle.isDened() implies conf.metaTitleAssociatedToProductType->includes(self.productType)) and (self.imageGalleryPath.isDened() implies conf.imageGalleryPathAssociatedToProductType->includes(self.productType)) and (self.baseImagePath.isDened() implies conf.baseImagePathAssociatedToProductType->includes(self.productType)) and (self.smallImagePath.isDened() implies conf.smallImagePathAssociatedToProductType->includes(self.productType)) and (self.thumbnailPath.isDened() implies conf.thumbnailPathAssociatedToProductType->includes(self.productType)) and (self.urlKey.isDened() implies conf.urlKeyAssociatedToProductType->includes(self.productType)) and (self.isAvailableForGoogleCheckout.isDened() implies conf.isAvailableForGoogleCheckoutAssociatedToProductType->includes(self.productType)) and (self.giftMessageAllowed.isDened() implies conf.giftMessageAllowedAssociatedToProductType->includes(self.productType)) and (self.visibleOnCatalog.isDened() implies conf.visibleOnCatalogAssociatedToProductType->includes(self.productType)) and (self.visibleOnSearch.isDened() implies conf.visibleOnSearchAssociatedToProductType->includes(self.productType))

249

context EditProduct :: mandatoryPropertiesAreRated() : Boolean body: let confType : ProductPropertiesTypeAssociationConguration = ProductPropertiesTypeAssociationConguration.allInstances() -> any(true) in let confOblig : ProductPropertiesObligatorinessConguration = ProductPropertiesObligatorinessConguration.allInstances() -> any(true) in ((confOblig.isNewFromIsMandatory and confType.isNewFromAssociatedToProductType->includes(self.productType)) implies self.isNewFrom.isDened()) and ((confOblig.isNewUntilIsMandatory and confType.isNewUntilAssociatedToProductType->includes(self.productType)) implies self.isNewUntil.isDened()) and ((confOblig.specialNetPriceIsMandatory and confType.specialNetPriceAssociatedToProductType->includes(self.productType)) implies self.specialNetPrice.isDened()) and ((confOblig.specialNetPriceFromIsMandatory and confType.specialNetPriceFromAssociatedToProductType->includes(self.productType)) implies self.specialNetPriceFrom.isDened()) and ((confOblig.specialNetPriceUntilIsMandatory and confType.specialNetPriceUntilAssociatedToProductType->includes(self.productType)) implies self.specialNetPriceUntil.isDened()) and ((confOblig.descriptionIsMandatory and confType.descriptionAssociatedToProductType->includes(self.productType)) implies self.description.isDened()) and ((confOblig.shortDescriptionIsMandatory and confType.shortDescriptionAssociatedToProductType->includes(self.productType)) implies self.shortDescription.isDened()) and ((confOblig.metaDescriptionIsMandatory and confType.metaDescriptionAssociatedToProductType->includes(self.productType)) implies self.metaDescription.isDened()) and ((confOblig.metaKeywordIsMandatory and confType.metaKeywordAssociatedToProductType->includes(self.productType)) implies self.metaKeyword -> forAll(k|k.isDened())) and ((confOblig.metaTitleIsMandatory and confType.metaTitleAssociatedToProductType->includes(self.productType)) implies self.metaTitle.isDened()) and ((confOblig.imageGalleryPathIsMandatory and confType.imageGalleryPathAssociatedToProductType->includes(self.productType)) implies self.imageGalleryPath.isDened()) and ((confOblig.baseImagePathIsMandatory and confType.baseImagePathAssociatedToProductType->includes(self.productType)) implies self.baseImagePath.isDened()) and ((confOblig.smallImagePathIsMandatory and confType.smallImagePathAssociatedToProductType->includes(self.productType)) implies self.smallImagePath.isDened()) and ((confOblig.thumbnailPathIsMandatory and confType.thumbnailPathAssociatedToProductType->includes(self.productType)) implies self.thumbnailPath.isDened()) and ((confOblig.urlKeyIsMandatory and confType.urlKeyAssociatedToProductType->includes(self.productType)) implies self.urlKey.isDened()) and ((confOblig.isAvailableForGoogleCheckoutIsMandatory and confType.isAvailableForGoogleCheckoutAssociatedToProductType->includes(self.productType)) implies self.isAvailableForGoogleCheckout.isDened()) and ((confOblig.giftMessageAllowedIsMandatory and confType.giftMessageAllowedAssociatedToProductType->includes(self.productType)) implies self.giftMessageAllowed.isDened()) and ((confOblig.visibleOnCatalogIsMandatory and confType.visibleOnCatalogAssociatedToProductType->includes(self.productType)) implies self.visibleOnCatalog.isDened()) and ((confOblig.visibleOnSearchIsMandatory and confType.visibleOnSearchAssociatedToProductType->includes(self.productType)) implies self.visibleOnSearch.isDened()) context EditProduct :: stockOptionsAreRatedOnlyForTheCorrectProductTypes() : Boolean body: ( self.productType=ProductType::Grouped or self.productType=ProductType::Congurable or self.productType=ProductType::Bundle ) implies ( self.quantity.isUndened() and self.qtyToBecomeOutOfStock.isUndened() and self.minQtyAllowedInShoppingCart.isUndened() and self.maxQtyAllowedInShoppingCart.isUndened() and self.notifyForQuantityBelow.isUndened()and

250

self.backOrderPolicy.isUndened() )

Effect
context EditProduct::effect() post productIsEdited: self.product.crossSellProduct = self.crossSellProduct and self.product.upSellProduct = self.upSellProduct and self.product.relatedProduct = self.relatedProduct and self.product.productTaxClass = self.productTaxClass and self.product.xedTaxRate = self.xedTaxRate and self.product.productInWebsite -> forAll (piw|piw.isAvailable = self.website->includes(piw.website)) post attributeRatingsAreEdited: self.values -> forAll ( v | if self.editForWebsiteScope.isDened() then v.a.websiteAttributeRating->any(war| war.websiteRatedProduct=self.product and war.websiteWhereIsRated=self.editForWebsiteScope ).redenedAttributeValue=v.v else if self.editForStoreViewScope.isDened() then v.a.storeViewAttributeRating->any(sar| sar.product=self.storeViewRatedProduct and sar.storeViewWhereIsRated=self.editForStoreViewScope ).redenedAttributeValue=v.v else v.a.globalAttributeRating->any(gar|gar.productOfGloballyRatedAttribute=self.product).genericAttributeValue=v.v endif endif ) post propertyRatingsAreEdited: if self.editForWebsiteScope.isDened() then let p : ProductInWebsite = self.product.productInWebsite->any(piw|piw.website=self.editForWebsiteScope) in p.redenedName = self.name and p.redenedNetPrice = self.netPrice and p.redenedWeight = self.weight and p.redenedStatus = self.status and p.redenedIsNewFrom = self.isNewFrom and p.redenedIsNewUntil = self.isNewUntil and p.redenedSpecialNetPrice = self.specialNetPrice and p.redenedSpecialNetPriceFrom = self.specialNetPriceFrom and p.redenedSpecialNetPriceUntil = self.specialNetPriceUntil and p.redenedDescription = self.description and p.redenedShortDescription = self.shortDescription and p.redenedMetaDescription = self.metaDescription and p.redenedMetaKeyword = self.metaKeyword and p.redenedMetaTitle = self.metaTitle and p.redenedImageGalleryPath = self.imageGalleryPath and p.redenedBaseImagePath = self.baseImagePath and p.redenedSmallImagePath = self.smallImagePath and p.redenedThumbnailPath = self.thumbnailPath and p.redenedUrlKey = self.urlKey and p.redenedIsAvailableForGoogleCheckout = self.isAvailableForGoogleCheckout and p.redenedGiftMessageAllowed = self.giftMessageAllowed and p.redenedVisibleOnCatalog = self.visibleOnCatalog and p.redenedVisibleOnSearch = self.visibleOnSearch else if self.editForStoreViewScope.isDened() then let p : ProductInStoreView = self.product.productInStoreView->any(pis|pis.storeView=self.editForStoreViewScope) in p.redenedName = self.name and p.redenedWeight = self.weight and p.redenedStatus = self.status and p.redenedIsNewFrom = self.isNewFrom and p.redenedIsNewUntil = self.isNewUntil and p.redenedSpecialNetPriceFrom = self.specialNetPriceFrom and p.redenedSpecialNetPriceUntil = self.specialNetPriceUntil and p.redenedDescription = self.description and p.redenedShortDescription = self.shortDescription and p.redenedMetaDescription = self.metaDescription and

251

p.redenedMetaKeyword = self.metaKeyword and p.redenedMetaTitle = self.metaTitle and p.redenedImageGalleryPath = self.imageGalleryPath and p.redenedBaseImagePath = self.baseImagePath and p.redenedSmallImagePath = self.smallImagePath and p.redenedThumbnailPath = self.thumbnailPath and p.redenedUrlKey = self.urlKey and p.redenedIsAvailableForGoogleCheckout = self.isAvailableForGoogleCheckout and p.redenedGiftMessageAllowed = self.giftMessageAllowed and p.redenedVisibleOnCatalog = self.visibleOnCatalog and p.redenedVisibleOnSearch = self.visibleOnSearch and let piw:ProductInWebsite = self.product.productInWebsite->any(piw|piw.website=self.editForStoreViewScope.store.website) in piw.redenedNetPrice = self.netPrice and piw.redenedSpecialNetPrice = self.specialNetPrice else self.product.genericName = self.name and self.product.genericNetPrice = self.netPrice and self.product.genericWeight = self.weight and self.product.genericStatus = self.status and self.product.genericIsNewFrom = self.isNewFrom and self.product.genericIsNewUntil = self.isNewUntil and self.product.genericSpecialNetPrice = self.specialNetPrice and self.product.genericSpecialNetPriceFrom = self.specialNetPriceFrom and self.product.genericSpecialNetPriceUntil = self.specialNetPriceUntil and self.product.genericDescription = self.description and self.product.genericShortDescription = self.shortDescription and self.product.genericMetaDescription = self.metaDescription and self.product.genericMetaKeyword = self.metaKeyword and self.product.genericMetaTitle = self.metaTitle and self.product.genericImageGalleryPath = self.imageGalleryPath and self.product.genericBaseImagePath = self.baseImagePath and self.product.genericSmallImagePath = self.smallImagePath and self.product.genericThumbnailPath = self.thumbnailPath and self.product.genericUrlKey = self.urlKey and self.product.genericIsAvailableForGoogleCheckout = self.isAvailableForGoogleCheckout and self.product.genericGiftMessageAllowed = self.giftMessageAllowed and self.product.genericVisibleOnCatalog = self.visibleOnCatalog and self.product.genericVisibleOnSearch = self.visibleOnSearch endif endif and self.product.sku = self.sku and self.product.stockStatus = self.stockStatus and self.product.quantity = self.quantity and self.product.qtyToBecomeOutOfStock = self.qtyToBecomeOutOfStock and self.product.minQtyAllowedInShoppingCart = self.minQtyAllowedInShoppingCart and self.product.maxQtyAllowedInShoppingCart = self.maxQtyAllowedInShoppingCart and self.product.notifyForQuantityBelow = self.notifyForQuantityBelow and self.product.backOrderPolicy = self.backOrderPolicy

Event

4.6.3

DeleteProduct

From use case: Delete a product

Event Specication
Generalizations Relationships inherited from ExistingProductEvent product : Product [1]

Effect
context DeleteProduct::effect()

252

post: not self.product@pre.oclIsKindOf(OclAny) and self.product@pre.tierPrice -> forAll ( t | not t@pre.oclIsKindOf(OclAny) ) and self.product@pre.review -> forAll ( t | not t@pre.oclIsKindOf(OclAny) ) and self.product@pre.option -> forAll ( o | not o@pre.oclIsKindOf(OclAny) ) and (self.product@pre.oclIsTypeOf(DownloadableProduct) implies self.product@pre.oclAsType(DownloadableProduct).downloadableItem -> forAll ( i | not i@pre.oclIsKindOf(OclAny) ) ) and (self.product@pre.oclIsTypeOf(BundleProduct) implies self.product@pre.oclAsType(BundleProduct).bundleItem -> forAll ( i | not i@pre.oclIsKindOf(OclAny) ) ) and

Event

4.6.4

MoveCategory

From use case: Move a product category

Event Specication
Relationships categoryToMove : Category [1] newParentCategory : Category [0..1]

Initial Integrity Constraints


context MoveCategory :: categoriesAreNotTheSame() : Boolean body: not self.categoryToMove = self.newParentCategory

Effect
context MoveCategory::effect() post: if self.newParentCategory.isDened() then self.categoryToMove.parent = self.newParentCategory else self.categoryToMove.parent->isEmpty() endif

Event

4.6.5

NewAttribute

From use case: Add an attribute

Event Specication
Attributes attributeType : AttributeType [1] code : String [1]

253

name : String [1] scope : Scope [1] isComparable : Boolean [1] hasUniqueValues : Boolean [0..1] isRequired : Boolean [0..1] associatedProductType : ProductType [1..*] inputValidation : InputValidation [0..1] isCongurable : Boolean [0..1] Relationships attributeSet : AttributeSet [1] allowedValue : EnumerationValue [*] defaultValue : AttributeValue [0..1]

Initial Integrity Constraints


context NewAttribute :: allowedEnumerationValuesAreOnlyDenedForEnumerationAttributes() : Boolean body: self.allowedValue -> notEmpty() = (self.attributeType = AttributeType::SingleValuedEnumeration or self.attributeType = AttributeType::MultipleValuedEnumeration) context NewAttribute :: isCongurablePropertyIsOnlyDenedForSingleValuedEnumerationAttributes() : Boolean body: self.allowedValue -> notEmpty() = self.attributeType = AttributeType::SingleValuedEnumeration context NewAttribute :: inputValidationIsOnlyDenedForTextualAttributes() : Boolean body: self.inputValidation.isDened() = self.attributeType = AttributeType::Textual context NewAttribute :: requiredAndUniqueAreOnlyDenedForNonImageAttributes() : Boolean body: (self.isRequired.isDened() and self.hasUniqueValues.isDened()) = (self.attributeType <> AttributeType::Image) context NewAttribute :: defaultValueIsNotDenedForImageAttributes() : Boolean body: self.attributeType = AttributeType::Image implies self.defaultValue.isDened() context NewAttribute :: defaultValueHaveTheCorrectType() : Boolean body: self.attributeType = AttributeType::Textual implies self.defaultValue.oclIsTypeOf ( TextualValue ) and self.attributeType = AttributeType::Price implies self.defaultValue.oclIsTypeOf ( PriceValue ) and self.attributeType = AttributeType::Date implies self.defaultValue.oclIsTypeOf ( DateValue ) and self.attributeType = AttributeType::Boolean implies self.defaultValue.oclIsTypeOf ( BooleanValue ) and self.attributeType = AttributeType::Integer implies self.defaultValue.oclIsTypeOf ( IntegerValue ) and self.attributeType = AttributeType::Decimal implies self.defaultValue.oclIsTypeOf ( DecimalValue ) and self.attributeType = AttributeType::SingleValuedEnumeration implies self.defaultValue.oclIsTypeOf ( EnumerationValue ) and self.attributeType = AttributeType::MultipleValuedEnumeration implies self.defaultValue.oclIsTypeOf ( MultipleEnumerationValue )

Effect
context NewAttribute::effect() post: a.oclIsNew() and a.oclIsKindOf(Attribute) and self.attributeType = AttributeType::Textual implies a.oclIsTypeOf(TextualAttribute) and

254

self.attributeType = AttributeType::Price implies a.oclIsTypeOf(PriceAttribute) and self.attributeType = AttributeType::Date implies a.oclIsTypeOf(DateAttribute) and self.attributeType = AttributeType::Boolean implies a.oclIsTypeOf(BooleanAttribute) and self.attributeType = AttributeType::Integer implies a.oclIsTypeOf(IntegerAttribute) and self.attributeType = AttributeType::Decimal implies a.oclIsTypeOf(DecimalAttribute) and self.attributeType = AttributeType::Image implies a.oclIsTypeOf(ImageAttribute) and self.attributeType = AttributeType::SingleValuedEnumeration implies a.oclIsTypeOf(SingleValuedEnumerationAttribute) and self.attributeType = AttributeType::MultipleValuedEnumeration implies a.oclIsTypeOf(MultipleValuedEnumerationAttribute) and a.code = self.code and a.genericName = self.name and a.scope = self.scope and a.isComparable = self.isComparable and a.hasUniqueValues = self.hasUniqueValues and a.isRequired = self.isRequired and a.associatedProductType = self.associatedProductType and (self.attributeType = AttributeType::Textual implies a.oclAsType(TextualAttribute).inputValidation = self.inputValidation) and (self.attributeType = AttributeType::SingleValuedEnumeration implies a.oclAsType(SingleValuedEnumerationAttribute).isCongurable = self.isCongurable) and ((self.attributeType = AttributeType::SingleValuedEnumeration or self.attributeType = AttributeType::SingleValuedEnumeration) implies a.oclAsType(EnumerationAttribute).allowedValue = self.allowedValue) and a.defaultValue = self.defaultValue and StoreView.allInstances() -> forAll ( stw | ais.oclIsNew() and ais.oclIsTypeOf(AttributeInStoreView) and ais.attribute = a and ais.storeView = stw ) and let productAbleToBeRated : Set(Product) = self.attributeSet.product -> select(p|a.associatedProductType -> includes(p.productType)) in productAbleToBeRated -> forAll ( p | gar.oclIsNew() and gar.oclIsTypeOf(GlobalAttributeRating) and gar.productOfGloballyRatedAttribute = p and gar.globallyRatedAttribute = a and Website.allInstances() -> forAll ( w | war.oclIsNew() and war.oclIsTypeOf(WebsiteAttributeRating) and war.websiteRatedProduct = p and war.websiteRatedAttribute = a and war.websiteWhereIsRated = w ) and StoreView.allInstances() -> forAll ( s | sar.oclIsNew() and sar.oclIsTypeOf(StoreViewAttributeRating) and sar.storeViewRatedProduct = p and sar.storeViewRatedAttribute = a and sar.storeViewWhereIsRated = s ))

Event

4.6.6

EditAttribute

From use case: Edit an attribute

Event Specication

Attributes attributeType : AttributeType [1] code : String [1] name : String [1] scope : Scope [1] isComparable : Boolean [1] hasUniqueValues : Boolean [0..1] isRequired : Boolean [0..1] associatedProductType : ProductType [1..*] inputValidation : InputValidation [0..1] isCongurable : Boolean [0..1] Relationships

255

attribute : Attribute [1] allowedValue : EnumerationValue [*] defaultValue : AttributeValue [0..1] Generalizations Relationships inherited from ScopeDenedEvent editForWebsiteScope : Website [0..1] editForStoreViewScope : StoreView [0..1]

Initial Integrity Constraints


context EditAttribute :: allowedEnumerationValuesAreOnlyDenedForEnumerationAttributes() : Boolean body: (self.attribute.oclIsTypeOf(SingleValuedEnumerationAttribute) or self.attribute.oclIsTypeOf(MultipleValuedEnumerationAttribute)) = self.attribute.oclAsType(EnumerationAttribute).allowedValue -> notEmpty() context EditAttribute :: isCongurablePropertyIsOnlyDenedForSingleValuedEnumerationAttributes() : Boolean body: self.allowedValue -> notEmpty() = self.attribute.oclIsTypeOf(SingleValuedEnumerationAttribute) context EditAttribute :: inputValidationIsOnlyDenedForTextualAttributes() : Boolean body: self.inputValidation.isDened() = self.attribute.oclIsTypeOf(TextualAttribute) context EditAttribute :: requiredAndUniqueAreOnlyDenedForNonImageAttributes() : Boolean body: (self.isRequired.isDened() and self.hasUniqueValues.isDened()) = (not self.attribute.oclIsTypeOf(ImageAttribute)) context EditAttribute :: defaultValueIsNotDenedForImageAttributes() : Boolean body: self.attribute.oclIsTypeOf(ImageAttribute) implies self.defaultValue.isDened() context EditAttribute :: defaultValueHaveTheCorrectType() : Boolean body: self.attribute.oclIsTypeOf(TextualAttribute) implies self.defaultValue.oclIsTypeOf ( TextualValue ) and self.attribute.oclIsTypeOf(PriceAttribute) implies self.defaultValue.oclIsTypeOf ( PriceValue ) and self.attribute.oclIsTypeOf(DateAttribute) implies self.defaultValue.oclIsTypeOf ( DateValue ) and self.attribute.oclIsTypeOf(BooleanAttribute) implies self.defaultValue.oclIsTypeOf ( BooleanValue ) and self.attribute.oclIsTypeOf(IntegerAttribute) implies self.defaultValue.oclIsTypeOf ( IntegerValue ) and self.attribute.oclIsTypeOf(DecimalAttribute) implies self.defaultValue.oclIsTypeOf ( DecimalValue ) and self.attribute.oclIsTypeOf(SingleValuedEnumerationAttribute) implies self.defaultValue.oclIsTypeOf ( EnumerationValue )) and self.attribute.oclIsTypeOf(MultipleValuedEnumerationAttribute) implies self.defaultValue.oclIsTypeOf ( MultipleEnumerationValue ))

Effect
context EditAttribute::effect() post: self.attribute.code = self.code and self.attribute.scope = self.scope and self.attribute.isComparable = self.isComparable and self.attribute.hasUniqueValues = self.hasUniqueValues and self.attribute.isRequired = self.isRequired and self.attribute.associatedProductType = self.associatedProductType and (self.attributeType = AttributeType::Textual implies self.attribute.oclAsType(TextualAttribute).inputValidation = self.inputValidation) and (self.attributeType = AttributeType::SingleValuedEnumeration implies self.attribute.oclAsType(SingleValuedEnumerationAttribute).-

256

isCongurable = self.isCongurable) and ((self.attributeType = AttributeType::SingleValuedEnumeration or self.attributeType = AttributeType::SingleValuedEnumeration) implies self.attribute.oclAsType(EnumerationAttribute).allowedValue = self.allowedValue) and self.attribute.defaultValue = self.defaultValue and if self.editForStoreViewScope.isDened() then self.attribute.attributeInStoreView->any( as|as.storeView=self.editForStoreViewScope ).redenedName = self.name else self.attribute.genericName = self.name endif

Event

4.6.7

DeleteAttribute

From use case: Delete an attribute

Event Specication
Relationships attribute : Attribute [1]

Effect
context DeleteAttribute::effect() post: not self.attribute@pre.oclIsKindOf(OclAny) and

257

4.7 Additional Activities

Event

4.7.1

NewReview

From use case: Add a review

Event Specication
Attributes authorNickName : String [1] title : String [1] text : String [1] scores : TupleType (value: Rating, property: Property) [1..*] Relationships product : Product [1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Initial Integrity Constraints


context NewReview :: customerIsLoggedInIfGuestsAreNotAllowed() : Boolean body: self.session.storeView.store.website.CatalogCongurationInWebsite.allowGuestsToWriteReviews or self.session.oclIsTypeOf(CustomerSession) context NewReview :: scoresAllVisibleProperties() : Boolean body: self.scores.property -> includesAll( self.session.storeView.propertyInStoreView->select(piw|piw.isVisible).property ) context NewReview :: reviewDoesNotExist() : Boolean body: not Review.allInstances()->exists ( r | r.authorNickName = self.authorNickName and r.text = self.text )

Effect
context NewReview::effect() post: r.oclIsNew() and r.oclIsTypeOf(Review) and r.authorNickName = self.authorNickName and r.title = self.title and r.text = self.text and r.status = ReviewStatus::Pending and r.createdAt = Now() and r.product = self.product and self.session.oclIsTypeOf(CustomerSession) implies r.user = self.session.oclAsType(CustomerSession).customer and r.storeViewWhereIsVisible -> includes(self.session.storeView) and self.scores -> forAll ( scoreTuple |

258

s.oclIsNew() and s.oclIsTypeOf(PropertyScore) and s.property = scoreTuple.property and s.review = r and s.value = scoreTuple.value )

Event

4.7.2

NewAdministratorReview

From use case: Add a review

Event Specication
Attributes authorNickName : String [1] title : String [1] text : String [1] status : ReviewStatus [1] scores : TupleType (value: Rating, property: Property) [1..*] Relationships product : Product [1] storeView : StoreView [1..*] Generalizations Relationships inherited from ExistingAdministratorEvent administrator : Administrator [1]

Initial Integrity Constraints


context NewAdministratorReview :: scoresAllVisibleProperties() : Boolean body: self.scores.property -> includesAll( self.storeView.propertyInStoreView->select(piw|piw.isVisible).property -> asSet() ) context NewAdministratorReview :: reviewDoesNotExist() : Boolean body: not Review.allInstances()->exists ( r | r.authorNickName = self.authorNickName and r.text = self.text )

Effect
context NewAdministratorReview::effect() post: r.oclIsNew() and r.oclIsTypeOf(Review) and r.authorNickName = self.authorNickName and r.title = self.title and r.text = self.text and r.status = self.status and r.createdAt = Now() and r.product = self.product and r.user = self.administrator and r.storeViewWhereIsVisible = self.storeView and r.scores -> forAll ( scoreTuple | s.oclIsNew() and s.oclIsTypeOf(PropertyScore) and s.property = scoreTuple.property and

259

s.review = r and s.value = scoreTuple.value )

Event

4.7.3

AddProductToWishlist

From use case: Add a product to the wish list

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context AddProductToWishlist :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty() context AddProductToWishlist :: wishListIsEnabledInTheCurrentWebsite() : Boolean body: self.customer.customerSession.storeView.store.website.wishlistCongurationInWebsite.status = Status::Enabled context AddProductToWishlist :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.customer.customerSession.storeView.store.website.productInWebsite->any( piw | piw.product = self.product ).isAvailable context AddProductToWishlist :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.customer.customerSession.storeView.productInStoreView->any( pisw | pisw.product = self.product ).status = #Enabled context AddProductToWishlist :: productIsNotAlreadyInWishList() : Boolean body: let currentWebsite : Website = self.customer.customerSession.storeView.store.website in self.customer.activityInfoOfCustomerInWebsite -> any ( ai | ai.websiteWithInfoAbout = currentWebsite ).wishedProduct -> excludes(self.product)

Effect

context AddProductToWishlist::effect() post: w.oclIsNew and w.oclIsTypeOf(WishListItem) and w.addedOn = Now() and w.wishedProduct = self.product and w.activityInfoOfCustomerInWebsite = self.customer.activityInfoOfCustomerInWebsite

260

->any( ai | ai.websiteWithInfoAbout = self.customer.customerSession.storeView.store.website )

Event

4.7.4

AddCommentToWishlistItem

From use case: Add a product to the wish list

Event Specication
Attributes newComment : String [1] Generalizations Relationships inherited from ExistingWishListItemEvent wishListItem : WishListItem [1] Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context AddCommentToWishlistItem :: wishListItemBelongsToCustomer() : Boolean body: self.wishListItem.activityInfoOfCustomerInWebsite.customerWithInfoAbout = self.customer

Effect
context AddCommentToWishlistItem::effect() post: self.wishListItem.comment = self.newComment

Event

4.7.5

RemoveCommentFromWishlistItem

From use case: Add a product to the wish list

Event Specication
Generalizations Relationships inherited from ExistingWishListItemEvent wishListItem : WishListItem [1] Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


261

context RemoveCommentFromWishlistItem :: wishListItemBelongsToCustomer() : Boolean body: self.wishListItem.activityInfoOfCustomerInWebsite.customerWithInfoAbout = self.customer

Effect
context RemoveCommentFromWishlistItem::effect() post: self.wishListItem.comment -> isEmpty()

Event

4.7.6

RemoveProductFromWishlist

From use case: Remove a product from the wish list

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context RemoveProductFromWishlist :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty() context RemoveProductFromWishlist :: productIsInTheWishList() : Boolean body: let currentWebsite : Website = self.customer.customerSession.storeView.store.website in self.customer.activityInfoOfCustomerInWebsite->any( ai | ai.websiteWithInfoAbout = currentWebsite ).wishedProduct -> includes(self.product)

Effect

context RemoveProductFromWishlist::effect() post: let currentWebsite : Website = self.customer.customerSession.storeView.store.website in self.customer.activityInfoOfCustomerInWebsite( ai | ai.websiteWithInfoAbout = currentWebsite ).wishedProduct -> excludes(self.product)

262

Event

4.7.7

AddProductToCompareList

From use case: Add a product to the compare list

Event Specication

Generalizations Relationships inherited from ExistingSessionEvent session : Session [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context AddProductToCompareList :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.session.storeView.store.website.productInWebsite->any(piw|piw.product = self.product).isAvailable context AddProductToCompareList :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.session.storeView.productInStoreView->any(pisw|pisw.product = self.product).status = Status::Enabled self.session.storeView.productInStoreView->any(pisw|pisw.product = self.product).status = Status::Enabled context AddProductToCompareList :: productIsNotAlreadyInCompareList() : Boolean body: self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .readyToCompareProduct -> excludes(self.product)

Effect
context AddProductToCompareList::effect() post: cope let listScope : Scope = self.session.storeView.store.website.catalogCongurationInWebsite.recentlyViewedAndComparedProductsSin if listScope = Scope::StoreView then self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.store-

View) .explicitReadyToCompareProduct -> includes(self.product) else self.session.activityInfoOfSessionInWebsite->any( ai | ai.websiteWithInfoAbout = self.session.storeView.store.website) .explicitReadyToCompareProduct -> includes(self.product) endif

263

Event

4.7.8

RemoveProductFromCompareList

From use case: Remove a product from the compare list

Event Specication

Generalizations Relationships inherited from ExistingSessionEvent session : Session [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context RemoveProductFromCompareList :: productIsInCompareList() : Boolean body: self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .readyToCompareProduct -> includes(self.product)

Effect
context RemoveProductFromCompareList::effect() post: self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .readyToCompareProduct -> excludes(self.product) post: cope let listScope : Scope = self.session.storeView.store.website.catalogCongurationInWebsite.recentlyViewedAndComparedProductsSin

let comparedProducts : OrderedSet(Product) = if listScope = Scope::StoreView then self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .explicitRecentlyComparedProduct else self.session.activityInfoOfSessionInWebsite->any( ai | ai.websiteWithInfoAbout = self.session.storeView.store.website) .explicitRecentlyComparedProduct endif in comparedProducts -> rst() = self.product and ( comparedProducts@pre -> size() = self.session.storeView.catalogCongurationInStoreView.numberOfRecentlyComparedProductsSaved implies comparedProducts -> excludes(comparedProducts@pre -> last()) )

Event

4.7.9

SingUpForPriceAlert

From use case: Subscribe to a product price alert

Event Specication
264

Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context SingUpForPriceAlert :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty() context SingUpForPriceAlert :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.customer.customerSession.storeView.store.website.productInWebsite->any( piw | piw.product = self.product ).isAvailable context SingUpForPriceAlert :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.customer.customerSession.storeView.productInStoreView->any( pisw | pisw.product = self.product ).status = #Enabled context SingUpForPriceAlert :: priceAlertIsAllowed() : Boolean body: self.customer.customerSession.storeView.catalogCongurationInStoreView.allowPriceAlert

Effect
context SingUpForPriceAlert::effect() post: self.customer.activityInfoOfCustomerInWebsite->any( ai | ai.websiteWithInfoAbout = self.customer.customerSession.storeView.store.website) .productSubscribedForPriceAlert -> includes(self.product)

Event

4.7.10

SingUpForStockAlert

From use case: Subscribe to a product stock alert

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


265

context SingUpForStockAlert :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty() context SingUpForStockAlert :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.customer.customerSession.storeView.store.website.productInWebsite->any( piw | piw.product = self.product ).isAvailable context SingUpForStockAlert :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.customer.customerSession.storeView.productInStoreView->any( pisw | pisw.product = self.product ).status = #Enabled context SingUpForStockAlert :: stockAlertIsAllowed() : Boolean body: self.customer.customerSession.storeView.store.website.catalogCongurationInWebsite.allowStockAlert

Effect
context SingUpForStockAlert::effect() post: self.customer.activityInfoOfCustomerInWebsite->any( ai | ai.websiteWithInfoAbout = self.customer.customerSession.storeView.store.website) .productSubscribedForStockAlert -> includes(self.product)

Event

4.7.11

SignUpForNewsletter

From use case: Subscribe to the newsletter

Event Specication
Attributes eMail : EMail [0..1] Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Initial Integrity Constraints


context SignUpForNewsletter :: sessionIsFromCustomerOrAnEmailIsProvided() : Boolean body: self.session.oclIsTypeOf(CustomerSession) or self.eMail.isDened() context SignUpForNewsletter :: anonymousSubscriptionDoesNotExistIfCurrentSessionIsAnonymous() : Boolean body: self.session.oclIsTypeOf(AnonymousSession) implies not AnonymousNewsletterSubscription.allInstances() -> exists ( s | s.storeView = self.session.storeView and s.providedEMail = self.eMail )

266

Effect
context SignUpForNewsletter::effect() post: if self.session.oclIsTypeOf(CustomerSession) then if self.session.oclAsType(CustomerSession).customer@pre.customerNewsletterSubscription -> exists( s | s.storeView = self.session.storeView ) then let subs : CustomerNewsletterSubscription = self.session.oclAsType(CustomerSession).customer.customerNewsletterSubscription -> any( s | s.storeView = self.session.storeView ) in subs.status = Status::Enabled and subs.providedEMail = self.eMail else if AnonymousSubscription@pre.allInstances() -> exists ( s | s.storeView = self.session.storeView and s.providedEMail = self.eMail ) then let subs : AnonymousNewsletterSubscription = AnonymousNewsletterSubscription@pre.allInstances() -> any ( s | s.storeView = self.session.storeView and s.providedEMail = self.eMail ) in subs.oclIsTypeOf(CustomerNewsletterSubscription) and subs.customer = self.session.oclAsType(CustomerSession).customer else s.oclIsNew() and s.oclIsTypeOf(CustomerNewsletterSubscription) and s.customer = self.session.oclAsType(CustomerSession).customer and s.providedEMail = self.eMail s.status = Status::Enabled and s.storeView = self.session.storeView endif endif else s.oclIsNew() and s.oclIsTypeOf(AnonymousNewsletterSubscription) and s.providedEMail = self.eMail and s.status = Status::Enabled and s.storeView = self.session.storeView endif

Event

4.7.12

SignDownFromNewsletter

From use case: Unsubscribe from the newsletter

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context SignDownFromNewsletter :: customerIsLoggedIn() : Boolean body: self.customer.customerSession -> notEmpty() context SignDownFromNewsletter :: customerHasAnEnabledSubscription() : Boolean body: self.customer.customerNewsletterSubscription -> exists ( s | s.storeView = self.customer.customerSession.storeView and s.status = Status::Enabled )

Effect
267

context SignDownFromNewsletter::effect() post: self.customer.customerNewsletterSubscription -> any ( s | s.storeView = self.customer.customerSession.storeView ).status = Status::Disabled

Event

4.7.13

TellToAFriendUsed

From use case: Tell to a friend

Event Specication
Generalizations Relationships inherited from ExistingSessionEvent session : Session [1]

Initial Integrity Constraints


context TellToAFriendUsed :: tellToAFriendIsEnabled() : Boolean body: self.session.storeView.tellToAFriendCongurationInStoreView.status = Status::Enabled context TellToAFriendUsed :: sessionBelongsToCustomerOrGuestIsEnabled() : Boolean body: self.session.storeView.tellToAFriendCongurationInStoreView.guestStatus = Status::Enabled or self.session.oclIsTypeOf(CustomerSession) context TellToAFriendUsed :: maxUsesNotReached() : Boolean body: let uses:Integer= self.session.activityInfoOfSessionInStoreView->any(ai|ai.storeViewWithInfoAbout=self.session.storeView) .usesOfTellToAFriendInLastHour in uses < self.session.storeView.tellToAFriendCongurationInStoreView.maxUsesPerHour

Effect

context TellToAFriendUsed::effect() post: let uses:Integer= self.session.activityInfoOfSessionInStoreView->any(ai|ai.storeViewWithInfoAbout = self.session.storeView).usesOfTellToAFriendInLastHour in uses = uses@pre +1

268

Event

4.7.14

ProductViewed

From use case: View product information, Place an Order

Event Specication

Generalizations Relationships inherited from ExistingSessionEvent session : Session [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context ProductViewed :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.session.storeView.store.website.productInWebsite->any(piw|piw.product = self.product).isAvailable context ProductViewed :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.session.storeView.productInStoreView->any(pisw|pisw.product = self.product).status = Status::Enabled context ProductViewed :: productIsNotAlreadyInRecentlyViewedList() : Boolean body: self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .recentlyViewedProduct -> excludes(self.product)

Effect
context ProductViewed::effect() post: cope let listScope : Scope = self.session.storeView.store.website.catalogCongurationInWebsite.recentlyViewedAndComparedProductsSin

let viewedProducts : OrderedSet(Product) = if listScope = Scope::StoreView then self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .explicitRecentlyViewedProduct else self.session.activityInfoOfSessionInWebsite->any( ai | ai.websiteWithInfoAbout = self.session.storeView.store.website) .explicitRecentlyViewedProduct endif in viewedProducts -> rst() = self.product and ( viewedProducts@pre -> size() = self.session.storeView.catalogCongurationInStoreView.numberOfRecentlyViewedProductsSaved implies viewedProducts -> excludes(viewedProducts@pre -> last()) )

269

Event

4.7.15

ResetTemporalInfo

From use case: Reset the temporal information

I I

Event Specication

Effect
context ResetTemporalInfo::effect() post: ActivityInfoOfSessionInStoreView.usesOfTellToAFriendInLastHour = 0 and ActivityInfoOfCustomerInStoreView.usesOfTellToAFriendInLastHour = 0

270

4.8 Online catalog

Event

4.8.1

ProductViewed

From use case: View product information, Place an Order

Event Specication
Generalizations Relationships inherited from ExistingSessionEvent session : Session [1] Relationships inherited from ExistingProductEvent product : Product [1]

Initial Integrity Constraints


context ProductViewed :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.session.storeView.store.website.productInWebsite->any(piw|piw.product = self.product).isAvailable context ProductViewed :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.session.storeView.productInStoreView->any(pisw|pisw.product = self.product).status = Status::Enabled context ProductViewed :: productIsNotAlreadyInRecentlyViewedList() : Boolean body: self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .recentlyViewedProduct -> excludes(self.product)

Effect
context ProductViewed::effect() post: cope let listScope : Scope = self.session.storeView.store.website.catalogCongurationInWebsite.recentlyViewedAndComparedProductsSin

let viewedProducts : OrderedSet(Product) = if listScope = Scope::StoreView then self.session.activityInfoOfSessionInStoreView->any( ai | ai.storeViewWithInfoAbout = self.session.storeView) .explicitRecentlyViewedProduct else self.session.activityInfoOfSessionInWebsite->any( ai | ai.websiteWithInfoAbout = self.session.storeView.store.website) .explicitRecentlyViewedProduct endif in viewedProducts -> rst() = self.product and ( viewedProducts@pre -> size() = self.session.storeView.catalogCongurationInStoreView.numberOfRecentlyViewedProductsSaved implies viewedProducts -> excludes(viewedProducts@pre -> last()) )

271

Event

4.8.2

AddProductToShoppingCart

From use case: Place an order

Event Specication

Attributes quantity : PositiveInteger [1] textOption : TupleType(o:TextOption,text:String) [*] dateOption : TupleType(o:DateOption,date:Date) [*] Relationships optionValue : OptionValueInOption [*] Generalizations Relationships inherited from ExistingProductEvent product : Product [1] Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Initial Integrity Constraints


context AddProductToShoppingCart :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.shoppingCart.currentStoreView.store.website.productInWebsite->any(piw| piw.product = self.product ).isAvailable context AddProductToShoppingCart :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.shoppingCart.currentStoreView.productInStoreView->any(pisw| pisw.product = self.product ).status = Status::Enabled context AddProductToShoppingCart :: productIsInStock() : Boolean body: self.product.stockStatus = StockStatus::InStock context AddProductToShoppingCart :: optionsAreFromTheProduct() : Boolean body: self.product.option -> includesAll(self.textOption->collect(o)) and self.product.option -> includesAll(self.dateOption->collect(o)) and self.product.option->select(o| o.oclIsTypeOf(OptionWithPredenedContent) ).oclAsType(OptionWithPredenedContent).optionValueInOption -> includesAll(self.optionValue) context AddProductToShoppingCart :: optionsAreRatedOnlyOnce() : Boolean body: self.textOption -> isUnique(o) and self.dateOption -> isUnique(o) and self.optionValue -> isUnique(optionWithPredenedContent) context AddProductToShoppingCart :: optionIsRatedWhenIsRequired() : Boolean body: self.product.option -> select(o|o.isRequired) -> forAll ( o | if o.oclIsTypeOf(TextOption) then self.textOption->collect(o) -> includes(o.oclAsType(TextOption)) else if o.oclIsTypeOf(DateOption) then

272

self.dateOption->collect(o) -> includes(o.oclAsType(DateOption)) else self.optionValue.optionWithPredenedContent -> includes(o) endif endif

Effect
context AddProductToShoppingCart::effect() post addProduct: let productExists: Boolean = let existingItem : ShoppingCartItem = self.shoppingCart@pre.shoppingCartItem@pre -> any(i|i.product=self.product) in existingItem.isDened() and existingItem.optionValueInOption = self.optionValue and existingItem.textOptionRating -> collect(r| Tupleo=r.textOption,text=r.value) = self.textOption and existingItem.dateOptionRating -> collect(r| Tupleo=r.textOption,date=r.value) = self.dateOption if productExists then let i = self.shoppingCart.shoppingCartItem -> any( i | i.product = self.product ) in i.quantity = i@pre.quantity + self.quantity else i.oclIsNew() and i.oclIsTypeOf(ShoppingCartItem) and i.shoppingCart = self.shoppingCart and i.product = self.product and i.quantity = self.quantity and i.applyDiscount = true and self.textOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(TextOptionRating) and r.textOption = tupleOpt.o and r.value = tupleOpt.text and r.shoppingCartItem = i ) and self.dateOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(DateOptionRating) and r.dateOption = tupleOpt.o and r.value = tupleOpt.date and r.shoppingCartItem = i ) and i.optionValueInOption = self.optionValue endif post decreaseQuantity: StockConguration.allInstances->any(true).decreaseStockWhenOrderIsPlaced implies (self.product.quantity = self.product@pre.quantity@pre - self.quantity) in

Event

4.8.3

UpdateShoppingCart

From use case: Place an order

Event Specication
Attributes lineChange : TupleType (remove: Boolean, quantity: PositiveInteger, customPrice: Money, applyDiscount: Boolean, item: ShoppingCartItem) [1..*] Generalizations Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Initial Integrity Constraints


context UpdateShoppingCart :: itemsAreUpdatedOnlyOnce() : Boolean

273

body: self.lineChange -> isUnique(item)

Effect
context UpdateShoppingCart::effect() post: self.lineChange -> forAll ( lc | let cartItem : ShoppingCartItem = self.shoppingCart.shoppingCartItem->any(i|i=lc.item) in if lc.remove then not cartItem@pre.oclIsKindOf(OclAny) else lc.quantity = cartItem.quantity and self.shoppingCart.oclIsTypeOf(AdministrationShoppingCart) implies ( cartItem.customPrice = lc.customPrice and cartItem.applyDiscount = lc.applyDiscount ) endif )

Event

4.8.4

ApplyCouponCode

From use case: Place an order, Add an order

Event Specication
Attributes newCouponCode : String [1] Generalizations Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Effect
context ApplyCouponCode::effect() post: self.shoppingCart.couponCode = self.newCouponCode

Event

4.8.5

OrderConrmation

From use case: Place an order, Add an order

Event Specication
274

Attributes comments : TupleType (text: String, notifyCustomer:Boolean) [*] creditCardInfo : TupleType (type: String, owner: String, number: String, expires: Date, verication: String) [0..1] eMailSent : Boolean [1] Relationships shoppingCart : ShoppingCart [1] delivery : Address [1] billing : Address [1] shippingMethod : ShippingMethod [1] paymentMethod : PaymentMethod [1]

Initial Integrity Constraints


context OrderConrmation :: guestCheckoutIsEnabledIfNeeded() : Boolean body: (self.shoppingCart.shoppingCartItem.product -> exists (p|p.oclIsTypeOf(DownloadableProduct)) and self.shoppingCart.currentStoreView.store.website.catalogCongurationInWebsite.allowGuestCheckoutForDownloadableItems) implies (not self.shoppingCart.oclIsTypeOf(AnonymousShoppingCart)) context OrderConrmation :: shippingMethodIsEnabledAtTheCurrentWebsite() : Boolean body: let sh:ShippingMethodInWebsite = self.shoppingCart.currentStoreview.store.website. shippingMethodInWebsite->any(sw|sw.shippingMethod = self.shippingMethod) in sh.status = Status::Enabled context OrderConrmation :: allowsFreeShippingOnlyForAMinimumAmount() : Boolean body: let sh:ShippingMethodInWebsite = self.shoppingCart.currentStoreview.store.website. shippingMethodInWebsite->any(sw|sw.shippingMethod = self.shippingMethod) in sh.oclIsTypeOf(FreeShippingInWebsite) implies self.shoppingCart.total >= sh.oclAsType(FreeShippingInWebsite).minimumOrderAmount context OrderConrmation :: paymentMethodIsEnabledAtTheCurrentWebsite() : Boolean body: let selectedMethodConguration : PaymentMethodInWebsite = self.shoppingCart.currentStoreView.store.website.paymentMethodInWebsite->any(sw|sw.paymentMethod = self.paymentMethod) in selectedMethodConguration.status = Status::Enabled and selectedMethodConguration.minimumAllowed <= self.shoppingCart.total and selectedMethodConguration.maximumAllowed >= self.shoppingCart .total context OrderConrmation :: creditCardDetailsAreThereIfNeeded() : Boolean body: self.paymentMethod.oclIsKindOf(CreditCardMethod) implies self.creditCardInfo.isDened()

Effect

context OrderConrmation::effect() post theOrderIsCreated: let taxConf : TaxCongurationInWebsite = self.shoppingCart@pre.currentStoreView.store.website.taxCon-

275

gurationInWebsite in let wbCurrency : Currency = self.shoppingCart@pre.currentStoreView.store.website.currencyCongurationInWebsite.baseCurrency in let purchCurrency : Currency = self.shoppingCart@pre.purchasingCurrency in o.oclIsNew() and o.oclIsTypeOf(Order) and o.couponCode = self.shoppingCart@pre.couponCode and o.eMailSent = self.eMailSent and o.giftMessage = self.shoppingCart@pre.giftMessage and o.storeView = self.shoppingCart@pre.currentStoreView and o.customerGroup = self.shoppingCart@pre.customerGroup and o.billing = self.billing and o.delivery = self.delivery and o.shippingMethod = self.shippingMethod and o.paymentMethod = self.paymentMethod and o.status = OrderStatus::Pending and self.shoppingCart.oclIsTypeOf(CustomerShoppingCart) implies o.customer = self.shoppingCart@pre.oclAsType(CustomerShoppingCart).customer@pre and self.shoppingCart.oclIsTypeOf(AdministrationShoppingCart) implies o.customer = self.shoppingCart@pre.oclAsType(AdministrationShoppingCart).customer@pre and o.rateApplicationAddress = if taxConf.usedAddress = TaxCalculatingAddress::Billing then o.billing else if taxConf.usedAddress = TaxCalculatingAddress::Delivery then o.delivery else taxConf.website.shippingCongurationInWebsite.shippingOrigin endif endif and o.genericBaseCurrency = CurrencyConguration.allInstances()->any(true).genericBaseCurrency and wbCurrency <> o.genericBaseCurrency implies (u.oclIsNew and u.oclIsTypeOf(UseOfWebsiteRedenedBaseCurrency) and u.orderOfRedenedBaseCurrency = o and u.websiteRedenedBaseCurrency = wbCurrency and u.initialRate = CurrencyRate.allInstances->any(r| r.baseCurrency=o.genericBaseCurrency and r.currency=wbCurrency ).rate) and (purchCurrency <> o.genericBaseCurrency and purchCurrency <> o.websiteRedenedBaseCurrency) implies (u.oclIsNew and u.oclIsTypeOf(UseOfPurchasingCurrency) and u.orderOfPurchasingCurrency = o and u.purchasingCurrency = purchCurrency and u.initialRate = CurrencyRate.allInstances->any(r| r.baseCurrency=o.genericBaseCurrency and r.currency=purchCurrency ).rate) and self.comments.forAll ( tupleCom | c.oclIsNew() and c.oclIsTypeOf(Comment) and c.text = tupleCom.text and c.notifyCustomer = tupleCom.notifyCustomer and c.createdAt = Now() and c.status = CommentStatus::Pending and o.comment -> includes(c) ) and self.shoppingCart@pre.shoppingCartItem@pre -> forAll ( i | ol.oclIsNew() and ol.oclIsTypeOf(OrderLine) and ol.order = o and ol.productSku = i.product.sku and ol.productName = i.product.productInStoreView -> any(pw|pw.storeView = o.storeView).name and ol.quantity = i.quantity and ol.giftMessage = i.giftMessage and ol.price = i.price and if i.applyDiscount then let discountBasis: Money = if self.shoppingCart.currentStoreView.store.website.taxCongurationInWebsite.methodRespectingDiscount = TaxRespectingDiscountsMethod::TaxAfterDiscount and self.shoppingCart.currentStoreView.store.website.taxCongurationInWebsite.applyDiscountIncludingTax then ol.price * ol.quantity + ol.tax else ol.price * ol.quantity endif in ol.discount = i.calculateDiscount( discountBasis, i.appliedShoppingCartPriceRule ) else ol.discount = 0.0 endif and let appliedTaxRate : Bag(TaxRate) = TaxRule.allInstances() -> select ( t | TaxRule.allInstances() -> forAll ( t2 | t2.priority <= t.priority ) ) ->select ( t | t.customerTaxClass -> includes(o.customerGroup.customerTaxClass) and t.productTaxClass -> includes(i.product) ) -> collect ( t | t.taxRate ) -> select ( tr | tr.applicableAddress -> includes(o.rateApplicationAddress) ) -> union ( i.product.xedTaxRate ) in

276

ol.tax = (appliedTaxRate -> collect ( a | a.rate * i.price * i.quantity / 100 ) -> sum()) and ol.total = (i.total + ol.tax) and ol.textOptions = TextOptionInfo.allInstances() -> select (inf| i.textOption.genericName -> includes(inf.optionName) and i.textOptionRating.value -> includes(inf.value) ) and ol.dateOptions = DateOptionInfo.allInstances() -> select (inf| i.dateOption.genericName -> includes(inf.optionName) and i.dateOptionRating.value -> includes(inf.value) ) and ol.predenedContentOptions = PredenedContentOptionInfo.allInstances() -> select (inf| i.optionValueInOption.optionWithPredenedContent.genericName -> includes(inf.optionName) and i.optionValueInOption.optionValue.genericName -> includes(inf.valueName) ) ) post theShoppingCartItemsAreRemoved: self.shoppingCart.shoppingCartItem -> isEmpty() post theShoppingCartIsRemovedIfItIsAdministration: self.shoppingCart@pre.oclIsTypeOf(AdministrationShoppingCart) implies (not self.shoppingCart@pre.oclIsTypeOf(OclAny)) post updateProductQuantities: StockConguration.decreaseStockWhenOrderIsPlaced implies self.shoppingCart@pre.shoppingCartItem@pre -> forAll ( i | i.product.quantity = i.product.quantity@pre - i.quantity )

Event

4.8.6

DuplicateAccount

From use case: Add an order

Event Specication
Relationships website : Website [1] Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1]

Initial Integrity Constraints


context DuplicateAccount :: customerIsNotVisibleInWebsite() : Boolean body: not self.website.visibleCustomer -> includes(self.customer)

Effect
context DuplicateAccount::effect() post: c.oclIsNew() and

277

c.oclIsTypeOf(Customer) and c.eMail = self.customer.eMail and c.rstName = self.customer.rstName and c.lastName = self.customer.lastName and c.password = self.customer.password and c.namePrex = self.customer.namePrex and c.middleName = self.customer.middleName and c.nameSufx = self.customer.nameSufx and c.dateOfBirth = self.customer.dateOfBirth and c.taxVatNumber = self.customer.taxVatNumber and c.createdAt = Now() and c.websiteWhereIsAssociated = self.website and c.customerGroup = CustomerGroup.allInstances() -> any(cg|cg.name=General) and c.address = self.customer.address and c.defaultBilling = self.customer.defaultBilling and c.defaultDelivery = self.customer.defaultDelivery

Event

4.8.7

NewAdministrationShoppingCart

From use case: Add an order

Event Specication
Generalizations Relationships inherited from ExistingCustomerEvent customer : Customer [1] Relationships inherited from ExistingAdministratorEvent administrator : Administrator [1] Relationships inherited from StoreViewPlacedEvent storeView : StoreView [1]

Effect
context NewAdministrationShoppingCart::effect() post: sc.oclIsNew() and sc.oclIsTypeOf(AdministrationShoppingCart) and sc.customer = self.customer and sc.administrator = self.administrator and sc.storeView = self.storeView and sc.currency = self.storeView.store.website.currencyCongurationInWebsite.baseCurrency

Event

4.8.8

AddProductToShoppingCart

From use case: Place an order

Event Specication
Attributes quantity : PositiveInteger [1] textOption : TupleType(o:TextOption,text:String) [*] dateOption : TupleType(o:DateOption,date:Date) [*] Relationships optionValue : OptionValueInOption [*]

278

Generalizations Relationships inherited from ExistingProductEvent product : Product [1] Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Initial Integrity Constraints


context AddProductToShoppingCart :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.shoppingCart.currentStoreView.store.website.productInWebsite->any(piw| piw.product = self.product ).isAvailable context AddProductToShoppingCart :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.shoppingCart.currentStoreView.productInStoreView->any(pisw| pisw.product = self.product ).status = Status::Enabled context AddProductToShoppingCart :: productIsInStock() : Boolean body: self.product.stockStatus = StockStatus::InStock context AddProductToShoppingCart :: optionsAreFromTheProduct() : Boolean body: self.product.option -> includesAll(self.textOption->collect(o)) and self.product.option -> includesAll(self.dateOption->collect(o)) and self.product.option->select(o| o.oclIsTypeOf(OptionWithPredenedContent) ).oclAsType(OptionWithPredenedContent).optionValueInOption -> includesAll(self.optionValue) context AddProductToShoppingCart :: optionsAreRatedOnlyOnce() : Boolean body: self.textOption -> isUnique(o) and self.dateOption -> isUnique(o) and self.optionValue -> isUnique(optionWithPredenedContent) context AddProductToShoppingCart :: optionIsRatedWhenIsRequired() : Boolean body: self.product.option -> select(o|o.isRequired) -> forAll ( o | if o.oclIsTypeOf(TextOption) then self.textOption->collect(o) -> includes(o.oclAsType(TextOption)) else if o.oclIsTypeOf(DateOption) then self.dateOption->collect(o) -> includes(o.oclAsType(DateOption)) else self.optionValue.optionWithPredenedContent -> includes(o) endif endif )

Effect
context AddProductToShoppingCart::effect() post addProduct: let productExists: Boolean = let existingItem : ShoppingCartItem = self.shoppingCart@pre.shoppingCartItem@pre -> any(i|i.product=self.product) in existingItem.isDened() and existingItem.optionValueInOption = self.optionValue and existingItem.textOptionRating -> collect(r| Tupleo=r.textOption,text=r.value) = self.textOption and existingItem.dateOptionRating -> collect(r| Tupleo=r.textOption,date=r.value) = self.dateOption in if productExists then let i = self.shoppingCart.shoppingCartItem -> any( i | i.product = self.product ) in i.quantity = i@pre.-

279

quantity + self.quantity else i.oclIsNew() and i.oclIsTypeOf(ShoppingCartItem) and i.shoppingCart = self.shoppingCart and i.product = self.product and i.quantity = self.quantity and i.applyDiscount = true and self.textOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(TextOptionRating) and r.textOption = tupleOpt.o and r.value = tupleOpt.text and r.shoppingCartItem = i ) and self.dateOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(DateOptionRating) and r.dateOption = tupleOpt.o and r.value = tupleOpt.date and r.shoppingCartItem = i ) and i.optionValueInOption = self.optionValue endif post decreaseQuantity: StockConguration.allInstances->any(true).decreaseStockWhenOrderIsPlaced implies (self.product.quantity = self.product@pre.quantity@pre - self.quantity)

Event

4.8.9

ChangeCurrencyOfAdministrationShoppingCart

From use case: Add an order

Event Specication
Relationships newCurrency : Currency [1] Generalizations

Effect
context ChangeCurrencyOfAdministrationShoppingCart::effect() post: self.shoppingCart.currency = self.newCurrency

Event

4.8.10

ChangeEMailAndGroupOfAdministrationShoppingCart

From use case: Add an order

Event Specication
Attributes newEMail : EMail [0..1] Relationships newCustomerGroup : CustomerGroup [0..1] Generalizations

280

Effect
context ChangeEMailAndGroupOfAdministrationShoppingCart::effect() post: self.shoppingCart.redenedCustomerEMail = self.newEMail and self.shoppingCart.redenedCustomerGroup = self.newCustomerGroup

Event

4.8.11

ApplyCouponCode

From use case: Place an order, Add an order

Event Specication
Attributes newCouponCode : String [1] Generalizations Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Effect
context ApplyCouponCode::effect() post: self.shoppingCart.couponCode = self.newCouponCode

Event

4.8.12

AddProductToShoppingCart

From use case: Place an order

Event Specication
Attributes quantity : PositiveInteger [1] textOption : TupleType(o:TextOption,text:String) [*] dateOption : TupleType(o:DateOption,date:Date) [*] Relationships optionValue : OptionValueInOption [*] Generalizations Relationships inherited from ExistingProductEvent product : Product [1] Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

281

Initial Integrity Constraints


context AddProductToShoppingCart :: productIsAvailableAtTheCurrentWebsite() : Boolean body: self.shoppingCart.currentStoreView.store.website.productInWebsite->any(piw| piw.product = self.product ).isAvailable context AddProductToShoppingCart :: productIsEnabledAtTheCurrentStoreView() : Boolean body: self.shoppingCart.currentStoreView.productInStoreView->any(pisw| pisw.product = self.product ).status = Status::Enabled context AddProductToShoppingCart :: productIsInStock() : Boolean body: self.product.stockStatus = StockStatus::InStock context AddProductToShoppingCart :: optionsAreFromTheProduct() : Boolean body: self.product.option -> includesAll(self.textOption->collect(o)) and self.product.option -> includesAll(self.dateOption->collect(o)) and self.product.option->select(o| o.oclIsTypeOf(OptionWithPredenedContent) ).oclAsType(OptionWithPredenedContent).optionValueInOption -> includesAll(self.optionValue) context AddProductToShoppingCart :: optionsAreRatedOnlyOnce() : Boolean body: self.textOption -> isUnique(o) and self.dateOption -> isUnique(o) and self.optionValue -> isUnique(optionWithPredenedContent) context AddProductToShoppingCart :: optionIsRatedWhenIsRequired() : Boolean body: self.product.option -> select(o|o.isRequired) -> forAll ( o | if o.oclIsTypeOf(TextOption) then self.textOption->collect(o) -> includes(o.oclAsType(TextOption)) else if o.oclIsTypeOf(DateOption) then self.dateOption->collect(o) -> includes(o.oclAsType(DateOption)) else self.optionValue.optionWithPredenedContent -> includes(o) endif endif )

Effect
context AddProductToShoppingCart::effect() post addProduct: let productExists: Boolean = let existingItem : ShoppingCartItem = self.shoppingCart@pre.shoppingCartItem@pre -> any(i|i.product=self.product) in existingItem.isDened() and existingItem.optionValueInOption = self.optionValue and existingItem.textOptionRating -> collect(r| Tupleo=r.textOption,text=r.value) = self.textOption and existingItem.dateOptionRating -> collect(r| Tupleo=r.textOption,date=r.value) = self.dateOption if productExists then let i = self.shoppingCart.shoppingCartItem -> any( i | i.product = self.product ) in i.quantity = i@pre.quantity + self.quantity else i.oclIsNew() and i.oclIsTypeOf(ShoppingCartItem) and i.shoppingCart = self.shoppingCart and i.product = self.product and i.quantity = self.quantity and i.applyDiscount = true and self.textOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(TextOptionRating) and r.textOption = tupleOpt.o and r.value = tupleOpt.text and r.shoppingCartItem = i ) and in

282

self.dateOption -> forAll(tupleOpt| r.oclIsNew() and r.oclIsTypeOf(DateOptionRating) and r.dateOption = tupleOpt.o and r.value = tupleOpt.date and r.shoppingCartItem = i ) and i.optionValueInOption = self.optionValue endif post decreaseQuantity: StockConguration.allInstances->any(true).decreaseStockWhenOrderIsPlaced implies (self.product.quantity = self.product@pre.quantity@pre - self.quantity)

Event

4.8.13

AddGiftMessage

From use case: Place an order, Add an order

Event Specication
Attributes newGiftMessage : String [1] Generalizations Relationships inherited from ExistingShoppingCartEvent shoppingCart : ShoppingCart [1]

Effect
context AddGiftMessage::effect() post: self.shoppingCart.giftMessage = newGiftMessage

Event

4.8.14

AddGiftMessageToItem

From use case: Place an order, Add an order

Event Specication
Attributes newGiftMessage : String [1] Relationships shoppingCartItem : ShoppingCartItem [1]

Effect
context AddGiftMessageToItem::effect() post:

283

self.shoppingCartItem.giftMessage = newGiftMessage

Event

4.8.15

OrderConrmation

From use case: Place an order, Add an order

Event Specication
Attributes comments : TupleType (text: String, notifyCustomer:Boolean) [*] creditCardInfo : TupleType (type: String, owner: String, number: String, expires: Date, verication: String) [0..1] eMailSent : Boolean [1] Relationships shoppingCart : ShoppingCart [1] delivery : Address [1] billing : Address [1] shippingMethod : ShippingMethod [1] paymentMethod : PaymentMethod [1]

Initial Integrity Constraints


context OrderConrmation :: guestCheckoutIsEnabledIfNeeded() : Boolean body: (self.shoppingCart.shoppingCartItem.product -> exists (p|p.oclIsTypeOf(DownloadableProduct)) and self.shoppingCart.currentStoreView.store.website.catalogCongurationInWebsite.allowGuestCheckoutForDownloadableItems) implies (not self.shoppingCart.oclIsTypeOf(AnonymousShoppingCart)) context OrderConrmation :: shippingMethodIsEnabledAtTheCurrentWebsite() : Boolean body: let sh:ShippingMethodInWebsite = self.shoppingCart.currentStoreview.store.website. shippingMethodInWebsite->any(sw|sw.shippingMethod = self.shippingMethod) in sh.status = Status::Enabled context OrderConrmation :: allowsFreeShippingOnlyForAMinimumAmount() : Boolean body: let sh:ShippingMethodInWebsite = self.shoppingCart.currentStoreview.store.website. shippingMethodInWebsite->any(sw|sw.shippingMethod = self.shippingMethod) in sh.oclIsTypeOf(FreeShippingInWebsite) implies self.shoppingCart.total >= sh.oclAsType(FreeShippingInWebsite).minimumOrderAmount context OrderConrmation :: paymentMethodIsEnabledAtTheCurrentWebsite() : Boolean body: let selectedMethodConguration : PaymentMethodInWebsite = self.shoppingCart.currentStoreView.store.website.paymentMethodInWebsite->any(sw|sw.paymentMethod = self.paymentMethod) in selectedMethodConguration.status = Status::Enabled and selectedMethodConguration.minimumAllowed <= self.shoppingCart.total and selectedMethodConguration.maximumAllowed >= self.shoppingCart .total context OrderConrmation :: creditCardDetailsAreThereIfNeeded() : Boolean

284

body: self.paymentMethod.oclIsKindOf(CreditCardMethod) implies self.creditCardInfo.isDened()

Effect

context OrderConrmation::effect() post theOrderIsCreated: let taxConf : TaxCongurationInWebsite = self.shoppingCart@pre.currentStoreView.store.website.taxCongurationInWebsite in let wbCurrency : Currency = self.shoppingCart@pre.currentStoreView.store.website.currencyCongurationInWebsite.baseCurrency in let purchCurrency : Currency = self.shoppingCart@pre.purchasingCurrency in o.oclIsNew() and o.oclIsTypeOf(Order) and o.couponCode = self.shoppingCart@pre.couponCode and o.eMailSent = self.eMailSent and o.giftMessage = self.shoppingCart@pre.giftMessage and o.storeView = self.shoppingCart@pre.currentStoreView and o.customerGroup = self.shoppingCart@pre.customerGroup and o.billing = self.billing and o.delivery = self.delivery and o.shippingMethod = self.shippingMethod and o.paymentMethod = self.paymentMethod and o.status = OrderStatus::Pending and self.shoppingCart.oclIsTypeOf(CustomerShoppingCart) implies o.customer = self.shoppingCart@pre.oclAsType(CustomerShoppingCart).customer@pre and self.shoppingCart.oclIsTypeOf(AdministrationShoppingCart) implies o.customer = self.shoppingCart@pre.oclAsType(AdministrationShoppingCart).customer@pre and o.rateApplicationAddress = if taxConf.usedAddress = TaxCalculatingAddress::Billing then o.billing else if taxConf.usedAddress = TaxCalculatingAddress::Delivery then o.delivery else taxConf.website.shippingCongurationInWebsite.shippingOrigin endif endif and o.genericBaseCurrency = CurrencyConguration.allInstances()->any(true).genericBaseCurrency and wbCurrency <> o.genericBaseCurrency implies (u.oclIsNew and u.oclIsTypeOf(UseOfWebsiteRedenedBaseCurrency) and u.orderOfRedenedBaseCurrency = o and u.websiteRedenedBaseCurrency = wbCurrency and u.initialRate = CurrencyRate.allInstances->any(r| r.baseCurrency=o.genericBaseCurrency and r.currency=wbCurrency ).rate) and (purchCurrency <> o.genericBaseCurrency and purchCurrency <> o.websiteRedenedBaseCurrency) implies (u.oclIsNew and u.oclIsTypeOf(UseOfPurchasingCurrency) and u.orderOfPurchasingCurrency = o and u.purchasingCurrency = purchCurrency and u.initialRate = CurrencyRate.allInstances->any(r| r.baseCurrency=o.genericBaseCurrency and r.currency=purchCurrency ).rate) and self.comments.forAll ( tupleCom | c.oclIsNew() and c.oclIsTypeOf(Comment) and c.text = tupleCom.text and c.notifyCustomer = tupleCom.notifyCustomer and c.createdAt = Now() and c.status = CommentStatus::Pending and o.comment -> includes(c) ) and self.shoppingCart@pre.shoppingCartItem@pre -> forAll ( i | ol.oclIsNew() and ol.oclIsTypeOf(OrderLine) and ol.order = o and ol.productSku = i.product.sku and ol.productName = i.product.productInStoreView -> any(pw|pw.storeView = o.storeView).name and ol.quantity = i.quantity and ol.giftMessage = i.giftMessage and ol.price = i.price and if i.applyDiscount then let discountBasis: Money = if self.shoppingCart.currentStoreView.store.website.taxCongurationInWebsite.methodRespectingDiscount = TaxRespectingDiscountsMethod::TaxAfterDiscount and self.shoppingCart.currentStoreView.store.website.taxCongurationInWebsite.applyDiscountIncludingTax then ol.price * ol.quantity + ol.tax

285

else ol.price * ol.quantity endif in ol.discount = i.calculateDiscount( discountBasis, i.appliedShoppingCartPriceRule ) else ol.discount = 0.0 endif and let appliedTaxRate : Bag(TaxRate) = TaxRule.allInstances() -> select ( t | TaxRule.allInstances() -> forAll ( t2 | t2.priority <= t.priority ) ) ->select ( t | t.customerTaxClass -> includes(o.customerGroup.customerTaxClass) and t.productTaxClass -> includes(i.product) ) -> collect ( t | t.taxRate ) -> select ( tr | tr.applicableAddress -> includes(o.rateApplicationAddress) ) -> union ( i.product.xedTaxRate ) ol.tax = (appliedTaxRate -> collect ( a | a.rate * i.price * i.quantity / 100 ) -> sum()) and ol.total = (i.total + ol.tax) and ol.textOptions = TextOptionInfo.allInstances() -> select (inf| i.textOption.genericName -> includes(inf.optionName) and i.textOptionRating.value -> includes(inf.value) ) and ol.dateOptions = DateOptionInfo.allInstances() -> select (inf| i.dateOption.genericName -> includes(inf.optionName) and i.dateOptionRating.value -> includes(inf.value) ) and ol.predenedContentOptions = PredenedContentOptionInfo.allInstances() -> select (inf| i.optionValueInOption.optionWithPredenedContent.genericName -> includes(inf.optionName) and i.optionValueInOption.optionValue.genericName -> includes(inf.valueName) ) ) post theShoppingCartItemsAreRemoved: self.shoppingCart.shoppingCartItem -> isEmpty() post theShoppingCartIsRemovedIfItIsAdministration: self.shoppingCart@pre.oclIsTypeOf(AdministrationShoppingCart) implies (not self.shoppingCart@pre.oclIsTypeOf(OclAny)) post updateProductQuantities: StockConguration.decreaseStockWhenOrderIsPlaced implies self.shoppingCart@pre.shoppingCartItem@pre -> forAll ( i | i.product.quantity = i.product.quantity@pre - i.quantity ) in

Event

4.8.16

DeleteAdministrationShoppingCart

From use case: Add an Order

Event Specication
Relationships administrationShoppingCart : AdministrationShoppingCart [1]

Effect
context DeleteAdministrationShoppingCart::effect() post:

286

not self.administrationShoppingCart@pre.oclIsKindOf(OclAny)

Event

4.8.17

CancelOrder

From use case: Cancel an order

Event Specication
Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context CancelOrder :: orderIsPendingOrProcessing() : Boolean body: self.order.status = OrderStatus::Pending or self.order.status = OrderStatus::Processing

Effect
context CancelOrder::effect() post: self.order.status = OrderStatus::Cancelled

Event

4.8.18

HoldOrder

From use case: Hold an order

Event Specication
Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context HoldOrder :: orderWasPendingOrProcessing() : Boolean body: self.order.status = OrderStatus::Pending or self.order.status = OrderStatus::Processing

Effect
287

context HoldOrder::effect() post: self.order.status = OrderStatus::Hold

Event

4.8.19

UnholdOrder

From use case: Unhold an order

Event Specication
Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context UnholdOrder :: orderWasHold() : Boolean body: self.order.status = OrderStatus::Hold

Effect
context UnholdOrder::effect() post: if self.order.invoice -> isEmpty() and self.order.shipment -> isEmpty() then self.order.status = OrderStatus::Pending else self.order.status = OrderStatus::Processing endif

Event

4.8.20

Reorder

From use case: Reorder

Event Specication
Relationships order : Order [1]

Initial Integrity Constraints


context Reorder :: orderIsPlacedByARegisteredCustomer() : Boolean body:

288

self.order.customer.isDened()

Effect
context Reorder::effect() post: let sc:CustomerShoppingCart=self.order.customer.customerShoppingCart in self.order.orderLine -> forAll ( ol | if sc@pre.product -> excludes(ol.product) then i.oclIsNew() and i.oclIsTypeOf(ShoppingCartItem) and i.shoppingCart = sc and i.product = ol.product and i.quantity = ol.quantity else let i = sc.shoppingCartItem -> any( i | i.product = ol.product ) in i.quantity = i@pre.quantity + ol.quantity endif )

Event

4.8.21

AddInvoice

From use case: Add an invoice

Event Specication

Attributes line : TupleType ( product:Product, quantity:PositiveInteger ) [1..*] eMailSent : Boolean [1] capturingMethod : InvoiceCapturingMethod [1] Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context AddInvoice :: orderAllowsMoreInvoices() : Boolean body: self.order.status = OrderStatus::Pending or self.order.status = OrderStatus::Processing context AddInvoice :: productsAreFromTheOrder() : Boolean body: self.line -> collect(product) -> forAll ( p | self.order.orderLine.productSku -> includes(p.sku) ) context AddInvoice :: quantitiesAreNotOverAllowedValues() : Boolean body: self.line -> forAll ( li | li.quantity = self.order.orderLine->any(info|info.productSku=li.product.sku).quantity )

289

Effect
context AddInvoice::effect() post createInvoice: i.oclIsNew and i.oclIsTypeOf(Invoice) and i.order = self.order and i.eMailSent = self.eMailSent and i.createdAt = Now() and i.capturingMethod = self.capturingMethod and i.isPaidOnline = ( self.order.paymentMethod.oclIsTypeOf(AuthorizeNet) or self.order.paymentMethod.oclIsTypeOf(PayFlowPro) or self.order.paymentMethod.oclIsKindOf(PayPalMethod) or self.order.paymentMethod.oclIsTypeOf(GoogleCheckout) ) and i.status = if self.capturingMethod = InvoiceCapturingMethod::PayLater and i.IsPaidOnline then InvoiceStatus::Pending else InvoiceStatus::Paid endif and self.line -> forAll ( line | il.oclIsNew() and il.oclIsTypeOf(InvoiceLine) and il.invoice = i and il.product = line.product and il.quantity = line.quantity ) post changeOrderStatus: if (self.order.nonReInvoiceableTotal < self.order.total or self.order.shipment.shipmentLine.quantity -> sum() < self.order.orderLine.quantity -> sum()) then self.order.status = OrderStatus::Processing else self.order.status = OrderStatus::Complete endif

Event

4.8.22

PayInvoice

From use case: Register an invoice payment

Event Specication
Relationships invoice : Invoice [1]

Initial Integrity Constraints


context PayInvoice :: invoiceWasPending() : Boolean body: self.invoice.status = Status::Pending

Effect
context PayInvoice::effect() post: self.invoice.status = Status::Paid

290

Event

4.8.23

CancelInvoice

From use case: Cancel an invoice

Event Specication
Relationships invoice : Invoice [1]

Initial Integrity Constraints


context CancelInvoice :: invoiceWasNotCancelled() : Boolean body: self.invoice.status <> Status::Cancelled

Effect
context CancelInvoice::effect() post: self.invoice.status = Status::Cancelled

Event

4.8.24

AddShipment

From use case: Add a shipment, Add an invoice

Event Specication
Attributes line : TupleType ( product:Product, quantity:PositiveInteger ) [1..*] eMailSent : Boolean [1] trackingNumber : TrackingNumber [*] Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context AddShipment :: orderAllowsMoreShipments() : Boolean body: self.order.status = OrderStatus::Pending or self.order.status = OrderStatus::Processing context AddShipment :: productsAreFromTheOrder() : Boolean body:

291

self.line -> collect(product) -> forAll ( p | self.order.orderLine.productSku -> includes(p.sku) ) context AddShipment :: quantitiesAreNotOverAllowedValues() : Boolean body: self.line -> forAll ( li | li.quantity = self.order.orderLine->any(info|info.productSku=li.product.sku).quantity )

Effect
context AddShipment::effect() post createShipment: s.oclIsNew and s.oclIsTypeOf(Shipment) and s.order = self.order and s.eMailSent = self.eMailSent and s.createdAt = Now() and s.trackingNumber = self.trackingNumber and and self.line -> forAll ( line | sl.oclIsNew() and sl.oclIsTypeOf(ShipmentLine) and sl.shipment = s and sl.orderLine.productSku = line.product.sku and sl.quantity = line.quantity ) post changeOrderStatus: if (self.order.nonReInvoiceableTotal < self.order.total or self.order.shipment.shipmentLine.quantity -> sum() < self.order.orderLine.quantity -> sum()) then self.order.status = OrderStatus::Processing else self.order.status = OrderStatus::Complete endif

Event

4.8.25

AddRefund

From use case: Add a refund

Event Specication
Attributes line : TupleType ( product:Product, quantity:PositiveInteger ) [1..*] eMailSent : Boolean [1] shippingAmount : Money [1] additionalAmount : Money [1] fee : Money [1] refundIsAlreadyReturned : Boolean [1] Generalizations Relationships inherited from ExistingOrderEvent order : Order [1]

Initial Integrity Constraints


context AddRefund :: orderAllowsMoreRefunds() : Boolean body: self.order.status = OrderStatus::Processing or self.order.status = OrderStatus::Complete

292

context AddRefund :: productsAreFromTheOrder() : Boolean body: self.line -> collect(product) -> forAll ( p | self.order.orderLine.productSku -> includes(p.sku) ) context AddRefund :: quantitiesAreNotOverAllowedValues() : Boolean body: self.line -> forAll ( li | li.quantity = self.order.invoice->select(i|i.status=Status::Paid).invoiceLine ->select(info|info.orderLine.productSku=li.product.sku).quantity->sum() )

Effect
context AddRefund::effect() post createRefund: r.oclIsNew and r.oclIsTypeOf(Refund) and r.order = self.order and r.eMailSent = self.eMailSent and r.createdAt = Now() and r.shippingAmount = self.shippingAmount and r.additionalAmount = self.additionalAmount and r.fee = self.fee and r.status = if self.refundIsAlreadyReturned then RefundStatus::Refunded else RefundStatus::Pending endif and self.line -> forAll ( line | rl.oclIsNew() and rl.oclIsTypeOf(RefundLine) and rl.refund = r and rl.product = line.product and rl.quantity = line.quantity ) post changeOrderStatus: self.order.totalRefunded = self.order.total implies self.order.status = OrderStatus::Closed

Event

4.8.26

CancelRefund

From use case: Cancel a refund

Event Specication
Relationships refund : Refund [1]

Initial Integrity Constraints


context CancelRefund :: refundWasNotCancelled() : Boolean body: self.refund.status <> Status::Cancelled

Effect
context CancelRefund::effect()

293

post: self.refund.status = Status::Cancelled

Event

4.8.27

AddComment

From use case: Add a comment to an order, invoice, shipment or refund.

Event Specication
Attributes text : String [1] notifyCustomer : Boolean [1] Relationships commentable : Commentable [1]

Effect
context AddComment::effect() post: co.oclIsNew() and co.oclIsTypeOf(Comment and co.text = self.text and co.notifyCustomer = self.notifyCustomer and co.createdAt = now() and co.status = CommentStatus::Pending

294

Das könnte Ihnen auch gefallen