gaber-elsayed

bill pdf

Mar 6th, 2021
45
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.31 KB | None | 0 0
  1.  
  2. ////////bill.js
  3.  
  4. /*global console require module*/
  5. 'use strict';
  6.  
  7. var express = require('express');
  8. var router = express.Router();
  9. var pdf = require('html-pdf');
  10. var cheerio = require('cheerio');
  11. var randomstring = require('randomstring');
  12. var debug = require('debug')('Foodbox-HQ:server');
  13. var format = require('string-format');
  14. var path = require('path')
  15.  
  16. format.extend(String.prototype);
  17. var config = require('../models/config');
  18. var conString = config.dbConn;
  19.  
  20. // Handlers for bill related code
  21.  
  22. // This returns the bill pdf given the file name
  23. router.get('/:id', function(req, res, next) {
  24. // XXX: Its better to group the files according to day/month than to
  25. // keep them in a single folder
  26. var bill_file_code = req.params.id;
  27. var filePath = process.env.BILL_FOLDER;
  28. filePath = path.join(filePath, 'bill-' + bill_file_code + '.pdf');
  29. res.sendFile(filePath);
  30. });
  31.  
  32. // This creates a pdf file from the given html and stores it.
  33. router.post('/', function(req, res, next) {
  34. // getting the bill html
  35. var bill_text = req.body.bill_text;
  36. // parsing it into cheerio struct
  37. var $ = cheerio.load(bill_text);
  38. // Filling the images in the html
  39. var filePath = path.join(__dirname, '/../');
  40. filePath = path.join(filePath, 'public/img/email.png');
  41. $("#mail img").attr("src", 'file://' + filePath);
  42.  
  43. filePath = path.join(__dirname, '/../');
  44. filePath = path.join(filePath, 'public/img/fb.png');
  45. $("#fb img").attr("src", 'file://' + filePath);
  46.  
  47. filePath = path.join(__dirname, '/../');
  48. filePath = path.join(filePath, 'public/img/twitter.png');
  49. $("#twitter img").attr("src", 'file://' + filePath);
  50.  
  51. var rand_string = randomstring.generate(5);
  52. var bill_file = 'bill-' + rand_string + '.pdf';
  53. var bill_folder = process.env.BILL_FOLDER;
  54. var options = { filename: path.join(bill_folder, bill_file), format: 'Letter' };
  55. debug('Bill location- ' + options.filename);
  56. // converting the pdf file to a buffer and passing it along to the print function
  57. pdf.create($.html(), options).toFile(function(err, buffer) {
  58. if (err) return console.error(err);
  59. debug('Bill {} successfully generated'.format(options.filename));
  60. res.send({"bill_location": "/bill/"+rand_string});
  61. });
  62. });
  63.  
  64. module.exports = router;
  65.  
  66.  
  67.  
  68. //////bill_generator_utils.js
  69.  
  70. /* global require __dirname module console */
  71. 'use strict';
  72.  
  73. var _ = require('underscore');
  74. var pg = require('pg');
  75. var async = require('async');
  76. var format = require('string-format');
  77. var moment = require('moment');
  78. var jsreport = require('jsreport');
  79. var path = require('path');
  80. var fs = require('fs');
  81. var dbUtils = require('../models/dbUtils')
  82.  
  83. format.extend(String.prototype);
  84. var config = require('../models/config');
  85. var conString = config.dbConn;
  86.  
  87. var prepare_and_store_bill_data = function(bill_date, outlet_id, callback) {
  88. debugger;
  89. pg.connect(conString, function(err, client, done) {
  90. if (err) {
  91. callback(err, null);
  92. return;
  93. }
  94. // Aggregate all bills
  95. var query_text =
  96. "SELECT \
  97. (select bill_no from bill_items where sales_order_id= so.id limit 1) as bill_no, \
  98. soi.sales_order_id as so_id, \
  99. soi.food_item_id as item_id, \
  100. coalesce(bi.quantity, soi.quantity) as qty, \
  101. so.outlet_id as outlet_id, \
  102. so.time as time, \
  103. soi.quantity as refund_qty, \
  104. r.id as fv_id, \
  105. r.name as fv_name, \
  106. r.address as fv_address, \
  107. r.phone_no as fv_phone, \
  108. r.st_no fv_st_no, \
  109. r.tin_no as fv_tin_no, \
  110. fi.name as item_name, \
  111. fi.mrp as mrp, \
  112. fi.selling_price as selling_price, \
  113. fi.service_tax_percent as st_perc, \
  114. fi.vat_percent as vat_perc, \
  115. fi.foodbox_fee as foodbox_fee, \
  116. fi.restaurant_fee as restaurant_fee, \
  117. fi.side_order as side_order_name, \
  118. o.start_of_day as start_of_day, \
  119. o.end_of_day as end_of_day, \
  120. o.is24hr as is24hr, \
  121. o.abatement_percent as abatement_perc \
  122. FROM \
  123. sales_order_items soi FULL OUTER JOIN \
  124. bill_items as bi ON bi.sales_order_id = soi.sales_order_id and bi.food_item_id = soi.food_item_id, \
  125. sales_order as so, \
  126. restaurant as r, \
  127. food_item as fi, \
  128. outlet as o \
  129. WHERE \
  130. DATE(so.time) >= $1 \
  131. AND \
  132. o.id = $2 \
  133. AND \
  134. so.outlet_id = o.id \
  135. AND \
  136. soi.sales_order_id = so.id \
  137. AND \
  138. coalesce(soi.food_item_id, bi.food_item_id) = fi.id \
  139. AND \
  140. r.id = fi.restaurant_id \
  141. ORDER BY bill_no asc";
  142.  
  143. var query_params = [bill_date, outlet_id];
  144.  
  145. client.query(query_text, query_params,
  146. function(query_err, query_res) {
  147. if(query_err) {
  148. done(client);
  149. callback(query_err, null);
  150. return;
  151. } else {
  152. debugger;
  153. var msg = 'Purchase Orders were issued on this day, but no Sales were made, so there are no bills to display.';
  154. done();
  155. var bills = query_res.rows;
  156. if(bills.length == 0) {
  157. callback(msg, null);
  158. return;
  159. }
  160. var first = _.first(bills);
  161. var filteredBills = [];
  162. if(first.is24hr) {
  163. filteredBills = _.filter(bills, function(b) {
  164. return (moment(b.time).format('YYYY-MM-DD') == bill_date);
  165. });
  166. } else {
  167. var last_eod,next_eod = null;
  168. if(first.start_of_day < first.end_of_day) {
  169. var prev_day = moment(bill_date).add(-1, 'days').format('YYYY-MM-DD');
  170. last_eod = moment(prev_day + ' ' + first.end_of_day);
  171. next_eod = moment(bill_date + ' ' + first.end_of_day).add(1, 'hours');
  172. } else {
  173. var next_day = moment(bill_date).add(1, 'days').format('YYYY-MM-DD');
  174. last_eod = moment(bill_date + ' ' + first.end_of_day);
  175. next_eod = moment(next_day + ' ' + first.end_of_day).add(1, 'hours');
  176. }
  177.  
  178. filteredBills = _.filter(bills, function(b) {
  179. return moment(b.time).isBetween(last_eod, next_eod);
  180. });
  181. }
  182. if(filteredBills.length == 0) {
  183. callback(msg, null);
  184. return;
  185. }
  186. dbUtils.store_daily_bill(bill_date, outlet_id, filteredBills, callback);
  187. return;
  188. }
  189. });
  190. });
  191. };
  192.  
  193. var fetch_bill_data = function(bill_date, outlet_id, fv_id, callback) {
  194. dbUtils.getArchivedBillData(outlet_id, bill_date, function(err, res){
  195. debugger;
  196. var msg = 'Purchase Orders were issued on this day, but no Sales were made, so there are no bills to display.';
  197. if(err){
  198. callback(msg, null);
  199. return;
  200. }
  201. var consolidated_bills = res;
  202. if (fv_id) {
  203. // filter result by fv.
  204. consolidated_bills = _.filter(res, function(row){
  205. return (row.fv_id == fv_id);
  206. });
  207. }
  208.  
  209. if(_.isEmpty(consolidated_bills)) {
  210. callback(msg, null);
  211. return;
  212. }
  213. callback(null, consolidated_bills);
  214. return;
  215. });
  216. };
  217.  
  218. var get_bill_bundle = function(bill_data, callback) {
  219. debugger;
  220. // Group bills by order id and food item id.
  221. var grouped_bills = [];
  222. var grouped = _.groupBy(bill_data, function(v) {
  223. return v.so_id + "#" + v.item_id;
  224. });
  225. _.each(_.keys(grouped), function(key){
  226. var bill = {};
  227. var orders = grouped[key];
  228. var sample = _.first(orders);
  229.  
  230. bill["bill_no"] = sample.bill_no;
  231. bill["so_id"] = sample.so_id;
  232. bill["time"] = moment(sample.time);
  233. bill["qty"] = sample.qty;
  234. var refunds = _.filter(orders, function(o){
  235. return (o.refund_qty && (o.refund_qty < 0));
  236. });
  237. bill["refund_qty"] = _.reduce(refunds, function(memo, o){
  238. return memo + o.refund_qty;
  239. }, 0);
  240.  
  241. bill["item_id"] = sample.item_id;
  242. bill["item_name"] = sample.item_name;
  243. bill["fv_id"] = sample.fv_id;
  244. bill["fv_name"] = sample.fv_name;
  245. bill["fv_address"] = sample.fv_address;
  246. bill["fv_phone"] = sample.fv_phone;
  247. bill["fv_st_no"] = sample.fv_st_no;
  248. bill["fv_tin_no"] = sample.fv_tin_no;
  249. bill["side_order_name"] = sample.side_order_name;
  250. bill["mrp"] = sample.mrp;
  251. bill["selling_price"] = sample.selling_price;
  252. bill["st_perc"] = sample.st_perc;
  253. bill["vat_perc"] = sample.vat_perc;
  254. bill["foodbox_fee"] = sample.foodbox_fee;
  255. bill["restaurant_fee"] = sample.restaurant_fee;
  256. bill["abatement_perc"] = sample.abatement_perc;
  257. grouped_bills.push(bill);
  258. });
  259.  
  260. // aggregate by bill no.
  261. var bills = [];
  262. var grouped = _.groupBy(grouped_bills, "bill_no");
  263. _.each(_.keys(grouped), function(bill_no) {
  264. var entries = grouped[bill_no];
  265. var fv_grouped = _.groupBy(entries, "fv_id");
  266. _.each(_.keys(fv_grouped), function(fv_id) {
  267. var bill = {};
  268. var first = fv_grouped[fv_id][0];
  269. bill["bill_no"] = bill_no;
  270. bill["fv_name"] = first["fv_name"];
  271. bill["fv_address"] = first["fv_address"] + " Ph:" + first["fv_phone"];
  272. bill["bill_date"] = moment(first["time"]).format('DD/MM/YYYY');
  273. bill["bill_time"] = moment(first["time"]).format('HH:mm:ss');
  274. bill["tin_no"] = first["fv_tin_no"];
  275. bill["st_no"] = first["fv_st_no"];
  276. bill["items"] = _.map(fv_grouped[fv_id], function(item) {
  277. var amount = Number(item.qty + item.refund_qty)*Number(item.selling_price);
  278. var mrp = Number(item.qty + item.refund_qty)*Number(item.mrp);
  279. var vat = Number(amount*item.vat_perc/100.0);
  280. if(item.vat_perc<5){
  281. amount+=vat;
  282. vat=0;
  283. }
  284. var st = mrp - amount - vat;
  285. return {
  286. name: item.item_name,
  287. qty: item.qty,
  288. refunds: item.refund_qty,
  289. amt: amount,
  290. display_amount: Number(amount.toFixed(2)),
  291. vat: vat,
  292. st: st,
  293. mrp: mrp
  294. };
  295. });
  296. debugger;
  297. bill["vat_percent"] = (first.vat_perc).toFixed(2);
  298. bill["st_percent"] = (first.st_perc*first.abatement_perc/100).toFixed(2);
  299. if ( first.vat_perc <5){ // value is harcoded
  300. bill["display_vat"]=false;
  301. }
  302. else{
  303. bill["display_vat"]=true;
  304.  
  305. }
  306. bill["total"] = _.reduce(bill["items"],
  307. function(memo, it) { return memo + it.amt;}, 0).toFixed(2);
  308.  
  309. bill["vat"] = _.reduce(bill.items, function(memo, it){
  310. return memo + it.vat;
  311. }, 0).toFixed(2);
  312.  
  313. bill["st"] = _.reduce(bill.items, function(memo, it){
  314. return memo + it.st;
  315. }, 0).toFixed(2);
  316.  
  317. bill["grand_total"] = _.reduce(bill.items, function(memo, it){
  318. return memo + it.mrp;
  319. }, 0).toFixed(2);
  320.  
  321. bills.push(bill);
  322. });
  323. });
  324. callback(null, bills);
  325. return;
  326. };
  327.  
  328. var generate_bill_bundle_pdf = function(bills, callback) {
  329. var template_path = path.join(__dirname, '/../');
  330. template_path = path.join(template_path, 'public/reports/bill_bundle.html');
  331. var content = fs.readFileSync(template_path, 'utf8');
  332. jsreport.render({
  333. template: {
  334. content: content,
  335. engine: 'jsrender'
  336. },
  337. recipe: 'phantom-pdf',
  338. data: {
  339. bills: bills
  340. },
  341. }).then(function(out) {
  342. callback(null, out);
  343. }).catch(function(err) {
  344. callback(err, null);
  345. return;
  346. });
  347. };
  348.  
  349. module.exports = {
  350. prepare_and_store_bill_data: prepare_and_store_bill_data,
  351. fetch_bill_data: fetch_bill_data,
  352. get_bill_bundle: get_bill_bundle,
  353. generate_bill_bundle_pdf: generate_bill_bundle_pdf
  354. };
Add Comment
Please, Sign In to add comment