@@ -441,51 +441,84 @@ module.exports = {
441
441
return order ;
442
442
} ,
443
443
444
- // Full refunds only
445
- refundOrder ( ) {
446
- throw new OrdersServiceError ( 'Not yet implemented' , 'NOT_IMPLEMENTED' ) ;
447
- // const order = await run(r.table('orders').get(id));
444
+ // Full order refund
445
+ async refundOrder ( id ) {
446
+ let order ;
447
+ try {
448
+ [ order ] = await sql `
449
+ SELECT
450
+ o.status AS order_status,
451
+ t.id AS transaction_id,
452
+ t.type AS transaction_type,
453
+ t.processor_transaction_id,
454
+ processor,
455
+ t.parent_transaction_id
456
+ FROM orders AS o
457
+ LEFT JOIN transactions AS t
458
+ ON o.id = t.order_id
459
+ WHERE
460
+ o.id = ${ id } ;
461
+ ` ;
462
+ } catch ( e ) {
463
+ throw new OrdersServiceError ( 'Could not query orders' , 'UNKNOWN' , e ) ;
464
+ }
448
465
449
- // if(!order) throw new OrdersServiceError('Order not found', 'NOT_FOUND');
466
+ if ( ! order ) throw new OrdersServiceError ( 'Order not found' , 'NOT_FOUND' ) ;
467
+ if ( order . orderStatus !== 'complete' ) throw new OrdersServiceError ( `Cannot refund order with status: ${ order . orderStatus } ` , 'REFUND_NOT_ALLOWED' ) ;
450
468
451
- // let refundResponse, orderStatus;
452
- // try {
453
- // const {status: processorStatus} = await gateway.order.find(order.braintreeTransactionId);
454
-
455
- // if(['settled', 'settling'].includes(processorStatus)) {
456
- // orderStatus = 'refunded';
457
- // refundResponse = await gateway.order.refund(order.braintreeTransactionId);
458
- // } else {
459
- // orderStatus = 'voided';
460
- // refundResponse = await gateway.order.void(order.braintreeTransactionId);
461
- // }
462
- // } catch(e) {
463
- // throw new OrdersServiceError('Order not refunded', 'BRAINTREE_ERROR', e);
464
- // }
469
+ const newTransaction = {
470
+ id : uuidV4 ( ) ,
471
+ orderId : id ,
472
+ processor : order . processor ,
473
+ parentTransactionId : order . transactionId
474
+ } ;
465
475
466
- // // Sometimes the call is successful but the refund is not
467
- // if(!refundResponse.success) throw new OrdersServiceError('Order not refunded', 'BRAINTREE_ERROR', refundResponse);
476
+ if ( order . processor === 'braintree' ) {
477
+ let processorResponse ;
478
+ try {
479
+ const { status : processorStatus } = await gateway . transaction . find ( order . processorTransactionId ) ;
480
+
481
+ if ( [ 'settled' , 'settling' ] . includes ( processorStatus ) ) {
482
+ processorResponse = await gateway . transaction . refund ( order . processorTransactionId ) ;
483
+ newTransaction . type = 'refund' ;
484
+ } else {
485
+ processorResponse = await gateway . transaction . void ( order . processorTransactionId ) ;
486
+ newTransaction . type = 'void' ;
487
+ }
488
+ } catch ( e ) {
489
+ throw new OrdersServiceError ( 'Order not refunded' , 'BRAINTREE_ERROR' , e ) ;
490
+ }
468
491
469
- // // Mark the order as refunded in our system, disable the guests and tickets
470
- // try {
471
- // // Synchronize this
472
- // const updated = r.now();
473
- // await Promise.all([
474
- // run(r.table('orders').get(id).update({status: orderStatus, updatedBy: username, updated})),
475
- // run(r.table('guests').filter({orderId: order.id}).update({status: 'archived', updatedBy: username, updated})),
476
- // run(r.table('tickets')
477
- // .getAll(
478
- // r.args(r.table('guests').filter({orderId: order.id})('id').coerceTo('array')),
479
- // {index: 'guestId'}
480
- // )
481
- // .update({status: 'disabled', updatedBy: username, updated}))
482
- // ]);
483
- // } catch(e) {
484
- // console.error(e);
485
- // throw new OrdersServiceError('Order voiding failed', 'UNKNOWN');
486
- // }
492
+ // Sometimes the call is successful but the refund is not
493
+ if ( ! processorResponse . success ) throw new OrdersServiceError ( 'Order not refunded' , 'BRAINTREE_ERROR' , processorResponse ) ;
494
+
495
+ newTransaction . processorTransactionId = processorResponse . transaction . id ;
496
+ newTransaction . processorCreatedAt = processorResponse . transaction . createdAt ;
497
+ newTransaction . amount = Number ( processorResponse . transaction . amount ) ;
498
+ } else {
499
+ throw new OrdersServiceError ( 'Order not refunded' , 'INVALID_PROCESSOR' ) ;
500
+ }
487
501
488
- // return refundResponse;
502
+ // Mark the order as canceled in our system, archive the guests
503
+ try {
504
+ await Promise . all ( [
505
+ sql `
506
+ INSERT INTO transactions ${ sql ( newTransaction ) }
507
+ ` ,
508
+ sql `
509
+ UPDATE orders
510
+ SET status = 'canceled'
511
+ WHERE id = ${ id }
512
+ ` ,
513
+ sql `
514
+ UPDATE guests
515
+ SET status = 'archived', updated = now()
516
+ WHERE order_id = ${ id }
517
+ `
518
+ ] ) ;
519
+ } catch ( e ) {
520
+ throw new OrdersServiceError ( 'Order voiding failed' , 'UNKNOWN' , e ) ;
521
+ }
489
522
} ,
490
523
491
524
transferOrderTickets ( ) {
0 commit comments