ekantin

transaction rollback

Mar 18th, 2019
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const verifyTokenPelanggan = require('../../helpers/verifyTokenPelanggan')
  2. const cariAdaOutletApaSajaDalamDataOrders = require('../../helpers/cariAdaOutletApaSajaDalamDataOrders')
  3. const hitungTotalPriceDariOrders = require('../../helpers/hitungTotalPriceOrders')
  4. const tanggalanConverter = require('../../helpers/tanggalanConverter')
  5. const rupiahConverter = require('../../helpers/rupiahConverter')
  6. const autoGenerateIdTransaksi = require('../../helpers/autoGenerateIdTransaksi')
  7. const Fawn = require('fawn')
  8. const sequelize = require('sequelize')
  9. const mongoose = require('mongoose')
  10. const mongoModel = require('../../mongoModels')
  11. const model = require('../../models')
  12. const moment = require('moment-timezone')
  13.  
  14. moment.locale('id')
  15. mongoose.Promise = global.Promise
  16. mongoose.connect(
  17.     'mongodb://' +
  18.         process.env.DATABASE_USER +
  19.         ':' +
  20.         process.env.DATABASE_PASSWORD +
  21.         '@' +
  22.         process.env.DATABASE_URI
  23. )
  24. Fawn.init(mongoose)
  25. var task = Fawn.Task()
  26.  
  27. async function addNewOrdersPelanggan(req, res, next) {
  28.     let kode_pelanggan = ''
  29.     let isKasir = true
  30.     // data Orderan dari client
  31.     let orders = req.body.orders
  32.     if (req.body.kode_pelanggan) {
  33.         kode_pelanggan = req.body.kode_pelanggan
  34.     } else {
  35.         // data pelanggan user, nanti convert nya dari token
  36.         kode_pelanggan = verifyTokenPelanggan(req.body.token)
  37.         isKasir = false
  38.     }
  39.     // split dulu ada kantin apa saja, ada hari apa aja
  40.     let listKantinYgMauDibuatTransaksi = cariAdaOutletApaSajaDalamDataOrders(
  41.         orders
  42.     )
  43.     // variable untuk nampung listOrder hasil filter berdasarkan tanggal dan kantin
  44.     let listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi = []
  45.     for (let i = 0; i < listKantinYgMauDibuatTransaksi.length; i++) {
  46.         // looping pertama, loop terus sampai list kantin yg ada habis
  47.         for (let j = 0; j < orders.length; j++) {
  48.             // looping kedua, loop sebanyak jumlah Orderan dari client
  49.             let hasilFilterOrderBerdasarkanKodeOutlet = []
  50.             for (let k = 1; k < 4; k++) {
  51.                 // looping ketiga, loop sebanyak 3 kali untuk loop istirahatnya
  52.                 let hasilFilterBerdasarkanIstirahat = orders[j]['istirahat' + k].filter(
  53.                     order => {
  54.                         // filter data orderan untuk istirahat ke-k
  55.                         if (order.kode_outlet == listKantinYgMauDibuatTransaksi[i]) {
  56.                             return order
  57.                         }
  58.                     }
  59.                 )
  60.                 if (hasilFilterBerdasarkanIstirahat.length > 0) {
  61.                     // ubah structure menjadi sesuai dengan kebutuhan di mongodb
  62.                     let generateToTransaksiDetailStructure = hasilFilterBerdasarkanIstirahat.map(
  63.                         detail => {
  64.                             let jam_ambil = null
  65.                             let obj = {
  66.                                 kode_menu: detail.id,
  67.                                 nama_menu: detail.menuName,
  68.                                 jam_istirahat: k,
  69.                                 jam_ambil: jam_ambil,
  70.                                 jumlah_pesan: detail.qty,
  71.                                 jumlah_ambil: 0,
  72.                                 jumlah_kembali: 0,
  73.                                 harga_beli: detail.price
  74.                             }
  75.                             return obj
  76.                         }
  77.                     )
  78.                     // gabungkan dengan variable penampung
  79.                     hasilFilterOrderBerdasarkanKodeOutlet = [
  80.                         ...hasilFilterOrderBerdasarkanKodeOutlet,
  81.                         ...generateToTransaksiDetailStructure
  82.                     ]
  83.                 }
  84.             }
  85.             // gabungkan dengan variable penampung per kantin dan per tanggal
  86.             if (hasilFilterOrderBerdasarkanKodeOutlet.length > 0) {
  87.                 // hitung total dari order berdasarkan tanggal dan kantin
  88.                 let total = hitungTotalPriceDariOrders(
  89.                     hasilFilterOrderBerdasarkanKodeOutlet
  90.                 )
  91.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi.push({
  92.                     date: orders[j].date,
  93.                     kode_outlet: listKantinYgMauDibuatTransaksi[i],
  94.                     orders: [...hasilFilterOrderBerdasarkanKodeOutlet],
  95.                     total: total
  96.                 })
  97.             }
  98.         }
  99.     }
  100.     // variable penampung data transaksi yg sudah tersimpan, untuk di rollback jika terjadi error / masuk catch
  101.     let newTransaksiTersimpan = []
  102.     let newUpdateOutletId = listKantinYgMauDibuatTransaksi
  103.     let newUpdateOutletTotal = []
  104.     let newUpdatePelangganTotal = 0
  105.     let newMutasiOutlet = []
  106.     let newMutasiPelanggan = []
  107.     for (let i = 0; i < listKantinYgMauDibuatTransaksi.length; i++) {
  108.         newUpdateOutletTotal.push(0)
  109.         newUpdatePelangganTotal = 0
  110.         for (
  111.             let j = 0;
  112.             j < listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi.length;
  113.             j++
  114.         ) {
  115.             newUpdatePelangganTotal +=
  116.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[j].total
  117.             if (
  118.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[j].kode_outlet ===
  119.                 listKantinYgMauDibuatTransaksi[i]
  120.             ) {
  121.                 newUpdateOutletTotal[i] +=
  122.                     listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[j].total
  123.             }
  124.         }
  125.         // task.update(mongoModel.Outlet, {
  126.         //   "_id": newUpdateOutletId[i]
  127.         // }, {
  128.         //   $inc: {
  129.         //     saldo: newUpdateOutletTotal[i]
  130.         //   }
  131.         // })
  132.     }
  133.     task.update(
  134.         mongoModel.Pelanggan,
  135.         {
  136.             _id: kode_pelanggan
  137.         },
  138.         {
  139.             $inc: {
  140.                 saldo: newUpdatePelangganTotal * -1
  141.             }
  142.         }
  143.     )
  144.     if (isKasir) {
  145.         let tanggalUntukNotif = moment().tz('Asia/Jakarta')
  146.         task.update(
  147.             mongoModel.Pelanggan,
  148.             {
  149.                 _id: kode_pelanggan
  150.             },
  151.             {
  152.                 $push: {
  153.                     notifikasi: {
  154.                         tanggal_waktu: tanggalUntukNotif,
  155.                         notifikasi:
  156.                             'Kamu melakukan pemesanan via kasir pada ' +
  157.                             tanggalanConverter(
  158.                                 new Date(
  159.                                     tanggalUntukNotif.year(),
  160.                                     tanggalUntukNotif.month(),
  161.                                     tanggalUntukNotif.date(),
  162.                                     tanggalUntukNotif.hour(),
  163.                                     tanggalUntukNotif.minute()
  164.                                 ),
  165.                                 true
  166.                             ) +
  167.                             ' sejumlah ' +
  168.                             rupiahConverter(newUpdatePelangganTotal),
  169.                         baca: 0
  170.                     }
  171.                 }
  172.             }
  173.         )
  174.     }
  175.     if (!isKasir) {
  176.         let tanggalUntukNotif = moment().tz('Asia/Jakarta')
  177.         let a = tanggalanConverter(
  178.             new Date(
  179.                 tanggalUntukNotif.year(),
  180.                 tanggalUntukNotif.month(),
  181.                 tanggalUntukNotif.date(),
  182.                 tanggalUntukNotif.hour(),
  183.                 tanggalUntukNotif.minute()
  184.             ),
  185.             true
  186.         )
  187.         let b = rupiahConverter(newUpdatePelangganTotal)
  188.         task.update(
  189.             mongoModel.Pelanggan,
  190.             {
  191.                 _id: kode_pelanggan
  192.             },
  193.             {
  194.                 $push: {
  195.                     notifikasi: {
  196.                         tanggal_waktu: tanggalUntukNotif,
  197.                         notifikasi:
  198.                             'Transaksi pemesanan via aplikasi pada ' +
  199.                             a +
  200.                             ' telah berhasil dilakukan ' +
  201.                             b,
  202.                         baca: 0
  203.                     }
  204.                 }
  205.             }
  206.         )
  207.     }
  208.     for (
  209.         let i = 0;
  210.         i < listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi.length;
  211.         i++
  212.     ) {
  213.         // looping sejumlah list orderan yg sudah di filter
  214.         let kode_kantin =
  215.             listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet[0] +
  216.             listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet[1] +
  217.             listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet[2] +
  218.             listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet[3] +
  219.             listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet[4]
  220.         // generate object lagi supaya sesuai untuk di simpan di mongodb
  221.         let jenis_transaksi = 0
  222.         if (isKasir) {
  223.             jenis_transaksi = 1
  224.         }
  225.         let obj = {
  226.             _id: await autoGenerateIdTransaksi(kode_kantin),
  227.             kode_pelanggan: kode_pelanggan,
  228.             kode_outlet:
  229.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].kode_outlet,
  230.             tanggal_ambil: new Date(
  231.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].date
  232.             ),
  233.             jenis_transaksi: jenis_transaksi,
  234.             transaksi_detail:
  235.                 listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].orders
  236.         }
  237.         try {
  238.             // proses pertama, menyimpan ke collection transaksi
  239.             newTransaksiTersimpan.push({
  240.                 _id: obj._id,
  241.                 kode_outlet: obj.kode_outlet,
  242.                 kode_pelanggan: obj.kode_pelanggan,
  243.                 total: listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi[i].total
  244.             })
  245.             task.save(mongoModel.Transaksi, obj)
  246.         } catch (e) {
  247.             // lakukan rollback jika terjadi error
  248.             console.log(e)
  249.             // hentikan looping
  250.             break
  251.         }
  252.         try {
  253.             let runTask = await task.run({ useMongoose: true })
  254.             let Sequelize = new sequelize(
  255.                 process.env.POSTGRE_DB,
  256.                 process.env.POSTGRE_USER,
  257.                 process.env.POSTGRE_PASSWORD,
  258.                 {
  259.                     isolationLevel:
  260.                         sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE ||
  261.                         'SERIALIZABLE',
  262.                     host: process.env.POSTGRE_HOST,
  263.                     dialect: process.env.POSTGRE_DIALECT
  264.                 }
  265.             )
  266.             Sequelize.transaction().then(function(t) {
  267.                 return Sequelize.Promise.map(newTransaksiTersimpan, function(ababi) {
  268.                     return model.Wallet.findOne({
  269.                         where: { kode_user: 'kotakmakan' },
  270.                         transaction: t
  271.                     }).then(function(walletEscrowKotakMakan) {
  272.                         return model.Wallet.findOne({
  273.                             where: { kode_user: ababi.kode_pelanggan },
  274.                             transaction: t
  275.                         }).then(function(walletPelanggan) {
  276.                             return walletEscrowKotakMakan
  277.                                 .increment({ saldo: ababi.total }, { transaction: t })
  278.                                 .then(function(walletEscrowKotakMakanBaru) {
  279.                                     let saldoBaruEscrow =
  280.                                         walletEscrowKotakMakanBaru.dataValues.saldo
  281.                                     let saldoLamaEscrow =
  282.                                         walletEscrowKotakMakanBaru._previousDataValues.saldo
  283.                                     return model.MutasiWallet.create(
  284.                                         {
  285.                                             kode_wallet: walletEscrowKotakMakan.kode_wallet,
  286.                                             tanggal_mutasi: moment(),
  287.                                             jenis_mutasi: 1,
  288.                                             saldo_awal: saldoLamaEscrow,
  289.                                             saldo_akhir: saldoBaruEscrow,
  290.                                             jumlah: ababi.total,
  291.                                             keterangan:
  292.                                                 'Pembayaran transaksi ' +
  293.                                                 ababi._id +
  294.                                                 ' tanggal ' +
  295.                                                 new Date(moment())
  296.                                         },
  297.                                         { transaction: t }
  298.                                     ).then(function(mutasiWallet) {
  299.                                         return walletPelanggan
  300.                                             .decrement({ saldo: ababi.total }, { transaction: t })
  301.                                             .then(function(walletPelangganBaru) {
  302.                                                 let saldoBaruPelanggan =
  303.                                                     walletPelangganBaru.dataValues.saldo
  304.                                                 let saldoLamaPelanggan =
  305.                                                     walletPelangganBaru._previousDataValues.saldo
  306.                                                 return model.MutasiWallet.create(
  307.                                                     {
  308.                                                         kode_wallet: walletPelanggan.kode_wallet,
  309.                                                         tanggal_mutasi: moment(),
  310.                                                         jenis_mutasi: 0,
  311.                                                         saldo_awal: saldoLamaPelanggan,
  312.                                                         saldo_akhir: saldoBaruPelanggan,
  313.                                                         jumlah: ababi.total,
  314.                                                         keterangan:
  315.                                                             'Pembayaran transaksi ' +
  316.                                                             ababi._id +
  317.                                                             ' tanggal ' +
  318.                                                             new Date(moment())
  319.                                                     },
  320.                                                     { transaction: t }
  321.                                                 )
  322.                                             })
  323.                                     })
  324.                                 })
  325.                         })
  326.                     })
  327.                 })
  328.                     .then(function(apada) {
  329.                         t.commit()
  330.                         res.send({
  331.                             statusCode: 200,
  332.                             body: {
  333.                                 data: listOrderPerKantinDanPerTanggalYgMauDibuatTransaksi
  334.                             },
  335.                             status: 'Request Success'
  336.                         })
  337.                     })
  338.                     .catch(err => {
  339.                         res.status(500).send({
  340.                             statusCode: 500,
  341.                             status: 'Request Failed',
  342.                             body: {
  343.                                 error: err.message
  344.                             }
  345.                         })
  346.                         t.rollback()
  347.                         doRollback(
  348.                             newTransaksiTersimpan,
  349.                             newUpdateOutletId,
  350.                             newUpdateOutletTotal,
  351.                             kode_pelanggan,
  352.                             newUpdatePelangganTotal,
  353.                             newMutasiOutlet,
  354.                             newMutasiPelanggan
  355.                         )
  356.                     })
  357.             })
  358.         } catch (e) {
  359.             doRollback(
  360.                 newTransaksiTersimpan,
  361.                 newUpdateOutletId,
  362.                 newUpdateOutletTotal,
  363.                 kode_pelanggan,
  364.                 newUpdatePelangganTotal,
  365.                 newMutasiOutlet,
  366.                 newMutasiPelanggan
  367.             )
  368.             res.status(500).send({
  369.                 statusCode: 500,
  370.                 status: 'Request Failed',
  371.                 body: {
  372.                     error: e.message
  373.                 }
  374.             })
  375.             console.log(e)
  376.         }
  377.     }
  378. }
  379.  
  380. function doRollback(
  381.     newTransaksiTersimpan,
  382.     newUpdateOutletId,
  383.     newUpdateOutletTotal,
  384.     kode_pelanggan,
  385.     newUpdatePelangganTotal,
  386.     newMutasiOutlet,
  387.     newMutasiPelanggan
  388. ) {
  389.     // proses pertama, delete collection transaksi
  390.     for (let i = 0; i < newTransaksiTersimpan.length; i++) {
  391.         mongoModel.Transaksi.remove({
  392.             _id: newTransaksiTersimpan[i]._id
  393.         })
  394.             .then(data => {
  395.                 console.log(i, 'transaksi')
  396.             })
  397.             .catch(e => {
  398.                 console.log(e)
  399.             })
  400.     }
  401.  
  402.     // proses kedua, update lagi saldo ke collection outlet
  403.     for (let i = 0; i < newUpdateOutletId.length; i++) {
  404.         let dataOutlet = mongoModel.Outlet.findByIdAndUpdate(newUpdateOutletId[i], {
  405.             $inc: {
  406.                 saldo: newUpdateOutletTotal[i] * -1
  407.             }
  408.         })
  409.             .then(data => {
  410.                 console.log(i, 'outlet')
  411.             })
  412.             .catch(e => {
  413.                 console.log(e)
  414.             })
  415.     }
  416.  
  417.     // proses ketiga, update lagi saldo ke collection pelanggan
  418.     let dataPelanggan = mongoModel.Pelanggan.findByIdAndUpdate(kode_pelanggan, {
  419.         $inc: {
  420.             saldo: newUpdatePelangganTotal
  421.         }
  422.     })
  423.         .then(data => {
  424.             console.log('0', 'pelanggan')
  425.         })
  426.         .catch(e => {
  427.             console.log(e)
  428.         })
  429.  
  430.     // // proses keempat, delete dari table mutasi wallet
  431.     // for (let i = 0; i < newMutasiOutlet.length; i++) {
  432.     //   let dataMutasiOutlet = model.MutasiWallet.destroy({where: {id: newMutasiOutlet[i].id}}).then((data) => {
  433.     //     console.log(data);
  434.     //   }).catch((e) => {
  435.     //     console.log(e);
  436.     //   })
  437.     // }
  438.     // for (let i = 0; i < newMutasiPelanggan.length; i++) {
  439.     //   let dataMutasiPelanggan = model.MutasiWallet.destroy({where: {id: newMutasiPelanggan[i].id}}).then((data) => {
  440.     //     console.log(data);
  441.     //   }).catch((e) => {
  442.     //     console.log(e);
  443.     //   })
  444.     // }
  445. }
  446.  
  447. module.exports = addNewOrdersPelanggan
Advertisement
Add Comment
Please, Sign In to add comment