PageSourceSearch

https://classic.ptotoday.com/components/com_store/app/services/order.service.js?6abe455424a3b

js ptotoday.com collected 2026-10-01 11:36:42 UTC 10,563 bytes, 375 lines download raw bytes

1"use strict";
2angular
3  .module("sfmStore")
4  .service("$order", function(APP_CONFIG, $http, $localStorage) {
5    var self = this;
6    this.plusTriggeredByOrder = 0;
7    this.order;
8
9    // We want to check local storage first to see if an order has been initiated already,
10    // if it has grab that order, otherwise start a fresh order.
11    (function() {
12      if ($localStorage.sfmOrder) {
13        self.order = $localStorage.sfmOrder;
14      } else {
15        self.order = {
16          profile: {},
17          school: {},
18          payment: {
19            pay_by_check: false
20          },
21          details: {
22            items: [],
23            coupon: {},
24            order_status: "STARTED",
25            total: 0,
26            cart_time: new Date()
27          }
28        };
29      }
30    })();
31
32    this.clear = function() {
33      self.order = {
34        profile: {},
35        school: {},
36        payment: {
37          pay_by_check: false
38        },
39        details: {
40          items: [],
41          coupon: {},
42          order_status: "STARTED",
43          total: 0,
44          cart_time: new Date()
45        }
46      };
47      this.persistOrder();
48    };
49
50    this.persistOrder = function() {
51      $localStorage.sfmOrder = this.order;
52    };
53
54    this.setExtended = function(value) {
55      if (value) {
56        this.order.details.extended = value;
57      } else {
58        this.order.details.extended = false;
59      }
60      this.persistOrder();
61    };
62
63    this.getExtended = function() {
64      if (this.order.details.extended) {
65        return this.order.details.extended;
66      }
67      return false;
68    };
69
70    this.updateProfile = function(profile) {
71      this.order.profile = profile || {};
72      this.persistOrder();
73    };
74
75    this.getProfile = function() {
76      if (
77        !angular.isUndefined(this.order.profile) &&
78        this.order.profile.email
79      ) {
80        return this.order.profile;
81      }
82      return {};
83    };
84
85    this.updateSchool = function(school) {
86      if (angular.isUndefined(school)) {
87        school = {
88          School_Name: null,
89          id: null
90        };
91      }
92      this.order.school = school || {};
93      this.order.profile.school_name = school.School_Name || "";
94      this.order.profile.school_id = school.id || "";
95      this.getTotal();
96    };
97
98    this.getSchool = function(field) {
99      if (
100        !angular.isUndefined(this.order.school) &&
101        this.order.school.School_Name
102      ) {
103        return this.order.school;
104      }
105      return false;
106    };
107
108    // We DO NOT want to store the user's credit card details in local storage.
109    this.updatePayment = function(payment, billing) {
110      this.order.payment = payment || {};
111      this.order.profile.billing = billing || {};
112    };
113
114    this.addOrderItem = function(item) {
115      var retVal = {
116        success: true
117      };
118      var items = this.order.details.items;
119
120      //If the user is trying to add an insurance or software item make sure there is only one in the cart'
121      if (item.type === "pkg" || item.type === "rnwl" || item.type === "software") {
122        const lookupType = item.type === "software" ? "software" : "pkg";
123        const productType = item.type === "software" ? "finance manager" : "insurance";
124        var dupItem = this.getDuplicateItem(lookupType);
125        if (dupItem) {
126          retVal = {
127            success: false,
128            error:
129              "You can only purchase one " + productType + " item at a time. '" +
130              item.title +
131              "' was not added to your cart."
132          };
133          return retVal;
134        }
135      }
136
137      // Check if the item has already been added to the cart, if so the conditional below increments the quantity
138      // rather than adding the item a second time to the cart.
139      var exists = items.filter(function(existingItem) {
140        return existingItem.id === item.id;
141      });
142
143      var newItem = {
144        id: item.id,
145        category_id: item.category_id,
146        name: item.title,
147        summary: item.introtext,
148        cost: item.cost,
149        cost_plus: item.cost_plus,
150        physical_item: item.physical_item,
151        allow_qty: item.allow_qty,
152        qty: Number(item.qty) || 1,
153        img: item.img,
154        type: item.type,
155        type_code: item.type_code
156      };
157
158      if (item.attendees) {
159        newItem.attendees = item.attendees || [];
160      }
161
162      if (item.questions) {
163        newItem.questions = item.questions || [];
164      }
165
166      if (item.subItems) {
167        newItem.subItems = item.subItems || [];
168      }
169
170      if (item.password) {
171        newItem.license = {
172          password: item.password
173        };
174      }
175
176      if (item.subscribers) {
177        newItem.subscribers = item.subscribers || [];
178      }
179
180      // for finance manager renewal
181      if (item.renewal) {
182        newItem.renewal = item.renewal
183      }
184
185      if (item.trial) {
186        newItem.trial = item.trial || "0"
187      }
188
189      if (exists.length === 0) {
190        items.push(newItem);
191      } else {
192        items.forEach(function(existingItem) {
193          if (existingItem.id === item.id && item.type !== "pkg") {
194            if (
195              Number(existingItem.qty) + Number(newItem.qty) >
196              APP_CONFIG.ITEM_MAX_QTY
197            ) {
198              existingItem.qty = APP_CONFIG.ITEM_MAX_QTY;
199            } else {
200              existingItem.qty = Number(existingItem.qty) + Number(newItem.qty);
201            }
202            existingItem = newItem;
203          }
204        });
205      }
206      this.getTotal();
207
208      return retVal;
209    };
210
211    this.removeOrderItem = function(idx) {
212      if (this.order.details.items.length > 0) {
213        this.order.details.items.splice(idx, 1);
214      }
215      this.getTotal();
216    };
217
218    this.removeAttendees = function(idx, qty) {
219      if (
220        this.order.details.items.length > 0 &&
221        this.order.details.items[idx].attendees
222      ) {
223        this.order.details.items[idx].attendees = this.order.details.items[
224          idx
225        ].attendees.slice(0, qty);
226      }
227      this.getTotal();
228    };
229
230    this.addCoupon = function(coupon) {
231      this.order.details.coupon = coupon;
232      this.getTotal();
233    };
234
235    this.removeCoupon = function() {
236      this.order.details.coupon = {};
237      this.getTotal();
238    };
239
240    this.getTotal = function() {
241      var total = 0;
242      var hasPlus = Number(this.order.school.plus);
243      if (!hasPlus || self.plusTriggeredByOrder) {
244        var subPlusItem = new Array();
245        var basePlusItem = this.order.details.items.filter(function(item) {
246          return item.type === "plus";
247        });
248        if (basePlusItem.length > 0) {
249          self.order.school.plus = 1;
250          hasPlus = 1;
251          self.plusTriggeredByOrder = 1;
252        } else if (basePlusItem.length === 0) {
253          angular.forEach(self.order.details.items, function(item) {
254            if (item.type === "pkg") {
255              subPlusItem = item.subItems.filter(function(subItem) {
256                return subItem.type === "plus";
257              });
258            }
259            if (subPlusItem.length > 0) {
260              self.order.school.plus = 1;
261              hasPlus = 1;
262              self.plusTriggeredByOrder = 1;
263            } else {
264              self.order.school.plus = 0;
265              hasPlus = 0;
266              self.plusTriggeredByOrder = 0;
267            }
268          });
269        }
270      }
271
272      this.order.details.items.forEach(function(item) {
273        var adjustedCost = calculateLineCost(item);
274        total += adjustedCost;
275      });
276      this.order.details.total = total;
277      this.persistOrder();
278      return total;
279    };
280
281    this.processOrder = function(data=null) {
282      if (data && this.order.payment.payment_method === 'pp') {
283        this.order.payment.paypal = {
284          orderID: data.orderID,
285          payerID: data.payerID 
286        }
287      }
288      return $http.post("/store?format=json&task=order.save", this.order);
289    };
290
291    this.startCart = function(data) {
292      return $http.post(
293        "/store?format=json&task=cartabandoned.api_addAbandoned",
294        data
295      );
296    };
297
298    this.completeCart = function(data) {
299      return $http.post(
300        "/store?format=json&task=cartabandoned.api_removeAbandoned",
301        data
302      );
303    };
304
305    var calculateLineCost = function(item) {
306      var price = item.cost;
307      var coupon = self.order.details.coupon;
308      var categoryExists = [];
309      var productExists = [];
310      if (Number(self.order.school.plus)) {
311        price = item.cost_plus;
312      }
313      // Handles multiple attendees for expos 
314      item.attendees !== undefined && item.attendees.length > 0  ? item.qty = item.attendees.length + 1 : item.qty;
315
316      price *= item.qty;
317      if (coupon.id) {
318        if (
319          angular.isDefined(coupon.coupon_categories) &&
320          angular.isArray(coupon.coupon_categories)
321        ) {
322          categoryExists = coupon.coupon_categories.filter(function(category) {
323            return category == item.category_id;
324          });
325        }
326        if (
327          angular.isDefined(coupon.coupon_products) &&
328          angular.isArray(coupon.coupon_products)
329        ) {
330          productExists = coupon.coupon_products.filter(function(product) {
331            return product == item.id;
332          });
333        }
334        if (categoryExists.length > 0 || productExists.length > 0) {
335          switch (coupon.coupon_type) {
336            case "amountoff":
337              if (price - coupon.coupon_amount >= 0) {
338                price -= coupon.coupon_amount;
339              }
340              break;
341            case "percentoff":
342              price = price - price * (coupon.coupon_amount / 100);
343              break;
344            case "twoforone":
345              var individualPrice = price / item.qty;
346              price -= Math.floor(item.qty / 2) * individualPrice;
347              break;
348            default:
349              break;
350          }
351        }
352      }
353      return price;
354    };
355
356    this.getOrder = function() {
357      return this.order;
358    };
359
360    /**
361     * It's likely that this function will be $watched so I only want to go through
362     * the loop once, as oppossed to every digest cycle.
363     * If we start updating the cart between page loads we'll need to loop every time this is called
364     */
365    this.getDuplicateItem = function(type) {
366      var _cartItem = false;
367      angular.forEach(self.order.details.items, function(item) {
368        if (item.type === type) {
369          _cartItem = item;
370        }
371      });
372
373      return _cartItem;
374    };
375  });

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.