00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef Order_HPP
00012 #define Order_HPP
00013
00014 #include "read_write_base.hpp"
00015
00016
00017 #include "ocTrustCommerce.h"
00018 #include "ocXML.h"
00019 #include "Product.hpp"
00020 #include "Ordered_Item_Option.hpp"
00021 #include "../admin/Product.hpp"
00022 #include "../admin/Size_Price.hpp"
00023 #include "../admin/ItemDetail.hpp"
00024 #include <set>
00025
00026 enum enm_order_status
00027 {
00028 os_awaiting_shipment=1,
00029 os_shipped,
00030 os_recieved,
00031 os_cancelled,
00032 os_returned,
00033 os_completed
00034 };
00035
00036
00037
00038
00039
00040
00041
00042 typedef set< llong > manufacturer_ids;
00043
00044 class Ordered_Obj: public read_write_base
00045 {
00046 public:
00047 identifier Id;
00048 llong Product_Id;
00049 llong Customer_Id;
00050 llong Order_Status_Id;
00051 money Product_Total;
00052 money Shipping_Total;
00053 money Tax_Total;
00054 money Order_Total;
00055 time_date Order_Date;
00056 time_date Ship_Date;
00057 time_date Reconcile_Date;
00058 string Transaction_Id;
00059 llong Shipping_Co;
00060 string Tracking_Number;
00061 string Notes;
00062 llong Customer_Pmt_Svc_Id;
00063 llong Promotion;
00064
00065
00066 items_ordered items;
00067
00068 manufacturer_ids manufacturers;
00069 double discount;
00070 bool freeShipping;
00071
00072 Ordered_Obj():read_write_base()
00073 ,Id(0LL)
00074 ,Product_Id(0LL)
00075 ,Customer_Id(0LL)
00076 ,Order_Status_Id(1LL)
00077 ,Product_Total(0.0)
00078 ,Shipping_Total(0.0)
00079 ,Tax_Total(0.0)
00080 ,Order_Total(0.0)
00081 ,Order_Date( )
00082 ,Ship_Date( )
00083 ,Reconcile_Date( )
00084 ,Transaction_Id("")
00085 ,Shipping_Co(0LL)
00086 ,Tracking_Number("")
00087 ,Notes("")
00088 ,Customer_Pmt_Svc_Id(0LL)
00089 ,Promotion(0LL)
00090 ,discount(0.0),freeShipping(false)
00091 {
00092
00093 data_name("Ordered");
00094
00095 addDXMap( new llongXfer("Id", &Id ));
00096 addDXMap( new llongXfer("Product_Id", &Product_Id ));
00097 addDXMap( new llongXfer("Customer_Id", &Customer_Id ));
00098 addDXMap( new llongXfer("Order_Status_Id", &Order_Status_Id ));
00099 addDXMap( new moneyXfer("Product_Total", &Product_Total ));
00100 addDXMap( new moneyXfer("Shipping_Total", &Shipping_Total ));
00101 addDXMap( new moneyXfer("Tax_Total", &Tax_Total ));
00102 addDXMap( new moneyXfer("Order_Total", &Order_Total ));
00103 addDXMap( new time_dateXfer("Order_Date", &Order_Date ));
00104 addDXMap( new time_dateXfer("Ship_Date", &Ship_Date ));
00105 addDXMap( new time_dateXfer("Reconcile_Date", &Reconcile_Date ));
00106 addDXMap( new stringXfer("Transaction_Id", &Transaction_Id ));
00107 addDXMap( new llongXfer("Shipping_Co", &Shipping_Co ));
00108 addDXMap( new stringXfer("Tracking_Number", &Tracking_Number ));
00109 addDXMap( new stringXfer("Notes", &Notes ));
00110 addDXMap( new llongXfer("Customer_Pmt_Svc_Id", &Customer_Pmt_Svc_Id ));
00111 addDXMap( new llongXfer("Promotion", &Promotion ));
00112 }
00113
00114 void shipInc (double & ship )
00115 {
00116 Shipping_Total.amount() += ship;
00117 }
00118
00119
00120 string netShipping( void )
00121 {
00122 return Shipping_Total.format("%n");
00123 }
00124
00125
00126 string setTax( void )
00127 {
00128
00129 globalTax.ProductTotal(Product_Total);
00130 Tax_Total = globalTax.TaxTotal();
00131 return Tax_Total.format("%n");
00132 }
00133 string setOrderTotal( void )
00134 {
00135 Order_Total.amount() = Product_Total.amount()
00136 + Shipping_Total.amount()
00137 + Tax_Total.amount();
00138 ocString formattedAmount = Order_Total.format("%n");
00139 return formattedAmount.remove("$").replaceAll(",","").remove(".");
00140 }
00141
00142
00143 double setOrderedItems( string XML )
00144 { xmlParser parser( XML );
00145 parser.parse();
00146 node_vector & xnodes = parser.nodeList();
00147 int i;
00148 Product_Total = 0.0;
00149
00150 for(i=0;i<xnodes.size();i++)
00151 {
00152
00153 ItemDetail dtl;
00154 dtl = xnodes[i];
00155
00156 ocString productId; productId.append(dtl.Product());
00157 ocString count; count.append(dtl.Count());
00158
00159 if( dtl.Product() )
00160 {
00161
00162 manufacturers.insert(dtl.Manufacturer());
00163
00164
00165 if(i==0)Product_Id = dtl.Product();
00166 Ordered_Item oi;
00167
00168 double mon = dtl.Price().amount();
00169 if( discount > 0.0 && discount < 100.0 )
00170 {
00171 mon *= (100-discount);
00172 mon /= 100.0;
00173 dtl.Price().amount() = mon;
00174 }
00175 long cnt = dtl.Count();
00176
00177 double ship = dtl.Shipping().amount();
00178 if( freeShipping )
00179 {
00180 ship = 0;
00181 dtl.Shipping().amount() = 0;
00182 }
00183
00184 oi.Product_Id = dtl.Product();
00185 oi.Order_Id = Id;
00186 oi.Product_Count = cnt;
00187 oi.Total_Price = ((double)cnt)*mon;
00188 oi.Shipping=ship*cnt;
00189 oi.Internal_Id = dtl.SKU();
00190 oi.External_Id = dtl.ProductName();
00191 shipInc(oi.Shipping.amount());
00192
00193 oi.addOrderItemOptions(xnodes[i]);
00194
00195 items.push_back(oi);
00196 Product_Total.amount() += oi.Total_Price.amount();
00197
00198 }
00199 }
00200 }
00201 bool saveOrderedItems( void )
00202 {
00203 bool bret = false;
00204 for( size_t i=0; i<items.size();++i)
00205 {
00206 items[i].Order_Id = Id;
00207 Ordered_Item_Obj toSave;
00208 toSave = items[i];
00209 bret = toSave.db_insert();
00210 if(bret) toSave.saveOptions();
00211 if( !bret ) break;
00212 }
00213 return bret;
00214 }
00215 bool decrementStock( void )
00216 {
00217 bool bret = false;
00218
00219 for( size_t i=0; i<items.size();++i)
00220 {
00221 Ordered_Item item = items[i];
00222 Product_Obj prod;
00223 prod.decrementStock(item.Product_Id,item.Product_Count);
00224 }
00225 return bret;
00226 }
00227 bool preauth( long long Payment_Service_Id )
00228 {
00229 bool bret = false;
00230
00231 netShipping();
00232 setTax();
00233
00234 Payment_Service ps;
00235 ps.key(Payment_Service_Id);
00236
00237 if( ps.get_data() && ps.getPaymentServiceParameters() )
00238 {
00239 Customer_Payment_Service pps;
00240 ocString where = "Customer_Id = ";
00241 where.append(Customer_Id);
00242 where += " and Payment_Service_Id = ";
00243 where.append(Payment_Service_Id);
00244
00245 if( pps.get_data(where) && pps.getParameters() )
00246 {
00247
00248 Customer_Pmt_Svc_Id = pps.Id;
00249 ocTCLink tcLink;
00250
00251
00252 pushParams( tcLink, ps, pps, pt_preauthorize );
00253
00254
00255 size_t pos2;
00256 for( pos2=0; pos2<pps.params.size();++pos2)
00257 {
00258 tcLink.PushParam(pps.params[pos2].Machine_Name,pps.params[pos2].Value);
00259 }
00260
00261 if( tcLink.Send().IsGood() )
00262 {
00263
00264 Transaction_Id = tcLink.TransactionId();
00265 bret = db_insert();
00266 Id = key();
00267 if( bret )
00268 {
00269 bret = saveOrderedItems();
00270
00271 decrementStock();
00272 }
00273 }
00274 else
00275 {
00276 m_result += "Payment Transaction Failed: ";
00277 m_result +=tcLink.TransactionInfo();
00278 }
00279 }
00280 else
00281 {
00282 m_result += "Customer payment setup failed: ";
00283 m_result += pps.last_result();
00284 }
00285 }
00286 else
00287 {
00288 m_result += "payment setup load failed: ";
00289 m_result += ps.last_result();
00290 }
00291 return bret;
00292 }
00293
00294
00295
00296
00297
00298
00299 bool removeParams()
00300 {
00301 ocString delSql = "delete from Customer_Payment_Parameter "
00302 "where Customer_Pmt_Service_Id = ";
00303 delSql.append(Customer_Pmt_Svc_Id);
00304 return cmd.execute(delSql);
00305 }
00306
00307 bool pay( long long Payment_Service_Id )
00308 {
00309 bool bret = false;
00310
00311 netShipping();
00312 setTax();
00313
00314 Payment_Service ps;
00315 ps.key(Payment_Service_Id);
00316
00317 if( ps.get_data() && ps.getPaymentServiceParameters() )
00318 {
00319 Customer_Payment_Service pps;
00320 ocString where = "Customer_Id = ";
00321 where.append(Customer_Id);
00322 where += " and Payment_Service_Id = ";
00323 where.append(Payment_Service_Id);
00324
00325 if( pps.get_data(where) && pps.getParameters() )
00326 {
00327
00328 Customer_Pmt_Svc_Id = pps.Id;
00329 ocTCLink tcLink;
00330
00331
00332 pushParams( tcLink, ps, pps, pt_pay );
00333
00334
00335 size_t pos2;
00336 for( pos2=0; pos2<pps.params.size();++pos2)
00337 {
00338 tcLink.PushParam(pps.params[pos2].Machine_Name,pps.params[pos2].Value);
00339 }
00340 if( tcLink.Send().IsGood() )
00341 {
00342
00343 Transaction_Id = tcLink.TransactionId();
00344 bret = db_insert();
00345 Id = key();
00346 if( bret )
00347 {
00348 bret = saveOrderedItems();
00349
00350 decrementStock();
00351 }
00352 }
00353 else
00354 {
00355 m_result += "Payment Transaction Failed: ";
00356 m_result +=tcLink.TransactionInfo();
00357 }
00358
00359 removeParams();
00360 }
00361 else
00362 {
00363 m_result += "Customer payment setup failed: ";
00364 m_result += pps.last_result();
00365 }
00366 }
00367 else
00368 {
00369 m_result += "payment setup load failed: ";
00370 m_result += ps.last_result();
00371 }
00372 return bret;
00373 }
00374
00375 bool postauth( void )
00376 {
00377 bool bret = false;
00378 m_result = "POST-AUTHORIZATION - ";
00379
00380 if( Id && Customer_Pmt_Svc_Id )
00381 {
00382 Customer_Payment_Service pps;
00383 pps.key(Customer_Pmt_Svc_Id);
00384 if( pps.get_data() )
00385 {
00386 Payment_Service ps;
00387 ps.key(pps.Payment_Service_Id);
00388 if( ps.get_data() && ps.getPaymentServiceParameters() )
00389 {
00390 ocTCLink tcLink;
00391
00392
00393 pushParams( tcLink, ps, pps, pt_postauthorize );
00394
00395
00396 if( tcLink.Send().IsGood() )
00397 {
00398 m_result += "Successful";
00399 bret = true;
00400 }
00401 else
00402 {
00403 m_result += "Payment Transaction Failed: ";
00404 m_result +=tcLink.TransactionInfo();
00405 }
00406 }
00407 }
00408 }
00409 return bret;
00410 }
00411
00412 bool credit( void )
00413 {
00414 bool bret = false;
00415 m_result = "CREDIT REVERSAL - ";
00416
00417 if( Id && Customer_Pmt_Svc_Id )
00418 {
00419 if( Order_Status_Id == os_shipped || Order_Status_Id ==os_recieved )
00420 {
00421 Customer_Payment_Service pps;
00422 pps.key(Customer_Pmt_Svc_Id);
00423 if( pps.get_data() )
00424 {
00425 Payment_Service ps;
00426 ps.key(pps.Payment_Service_Id);
00427 if( ps.get_data() && ps.getPaymentServiceParameters() )
00428 {
00429 ocTCLink tcLink;
00430
00431
00432 pushParams( tcLink, ps, pps, pt_reverse );
00433
00434
00435 if( tcLink.Send().IsGood() )
00436 {
00437 m_result += "Successful";
00438 Order_Status_Id = os_cancelled;
00439 bret = true;
00440 }
00441 else
00442 {
00443 m_result += "Payment Transaction Failed: ";
00444 m_result +=tcLink.TransactionInfo();
00445 }
00446 }
00447 }
00448 }
00449 else
00450 {
00451 m_result += "No Payment Transaction reversal until payment is made!";
00452 }
00453
00454
00455 }
00456 return bret;
00457 }
00458
00459 void pushParams( ocTCLink & tcLink, Payment_Service & ps, Customer_Payment_Service & pps, param_types ptype )
00460 {
00461
00462 Payment_Type_Parameters::iterator pos1;
00463 for( pos1=ps.sys_params.lower_bound(pt_all); pos1!=ps.sys_params.upper_bound(pt_all); ++pos1 )
00464 {
00465 tcLink.PushParam(pos1->second.Machine_Name,pos1->second.Value);
00466 }
00467
00468 for( pos1=ps.sys_params.lower_bound(ptype); pos1!=ps.sys_params.upper_bound(ptype); ++pos1 )
00469 {
00470 tcLink.PushParam(pos1->second.Machine_Name,pos1->second.Value);
00471 }
00472
00473 for( pos1=ps.dyn_params.lower_bound(ptype); pos1!=ps.dyn_params.upper_bound(ptype); ++pos1 )
00474 {
00475 tcLink.PushParam(pos1->second.Machine_Name,dynValue(pos1->second.Value_Location));
00476 }
00477 }
00478
00479
00480
00481
00482 string dynValue( long loco )
00483 {
00484 ocString value;
00485 if( loco==pml_dynamic_order_id)
00486 {
00487 value.append(Customer_Id);
00488 value+="-";
00489 value.append(Product_Id);
00490 }
00491 else if( loco==pml_dynamic_amount)
00492 {
00493 value=setOrderTotal();
00494 }
00495 else if( loco==pml_dynamic_tran_id )
00496 {
00497 value= Transaction_Id;
00498 }
00499 return value;
00500 }
00501
00502
00503 bool uvalidate( void )
00504 {
00505
00506 ocString sqlStatus = "select Order_Status_Id from Orders where Id = ";
00507 sqlStatus.append(key());
00508 if( rs.open(sqlStatus) )
00509 {
00510 long long statusVal = atoll(rs.getField(0).format().c_str());
00511 rs.close();
00512
00513 if( statusVal == Order_Status_Id ||
00514 ( statusVal > os_awaiting_shipment &&
00515 Order_Status_Id > os_awaiting_shipment
00516 ) )
00517 {
00518 return true;
00519 }
00520 else if( statusVal == os_awaiting_shipment &&
00521 ( Order_Status_Id == os_shipped ||
00522 Order_Status_Id == os_recieved ) )
00523 {
00524
00525 if( postauth() )
00526 {
00527
00528 Ship_Date.now();
00529
00530
00531
00532 Reconcile_Date.now();
00533 Reconcile_Date.addMonths(1);
00534
00535
00536
00537 return true;
00538 }
00539 }
00540 else if( statusVal == os_awaiting_shipment &&
00541 ( Order_Status_Id == os_cancelled ||
00542 Order_Status_Id == os_returned ) )
00543 {
00544
00545 if( credit() )
00546
00547 return true;
00548 }
00549 else
00550 {
00551 m_result = "<b>NO CHANGE MADE!</b> It's illegal to change the status that way!";
00552 }
00553 }
00554 return false;
00555 }
00556
00557 };
00558
00559 #endif
00560