From 67b7c5aa9abb3096d929e5a067014ab912dbdfa6 Mon Sep 17 00:00:00 2001 From: arsalan Date: Thu, 7 Mar 2024 18:01:23 +0530 Subject: [PATCH] add payment, invoice --- excel/Invoices.xls | Bin 0 -> 8704 bytes excel/Payments.xls | Bin 0 -> 5120 bytes excel/Products.xls | Bin 7168 -> 7680 bytes excel/Quotes.xls | Bin 14848 -> 18432 bytes .../com/restapi/controllers/Entities.kt | 32 ++++--- .../kotlin/com/restapi/controllers/Excel.kt | 84 +++++++++++++++++- .../kotlin/com/restapi/controllers/Filters.kt | 6 +- src/main/kotlin/com/restapi/domain/models.kt | 6 +- src/main/resources/dbmigration/1.14.sql | 2 + .../dbmigration/model/1.14.model.xml | 8 ++ 10 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 excel/Invoices.xls create mode 100644 excel/Payments.xls create mode 100644 src/main/resources/dbmigration/1.14.sql create mode 100644 src/main/resources/dbmigration/model/1.14.model.xml diff --git a/excel/Invoices.xls b/excel/Invoices.xls new file mode 100644 index 0000000000000000000000000000000000000000..7d8d37573aa0ca4fcb428b9cdf2bacce2781474a GIT binary patch literal 8704 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 literal 0 HcmV?d00001 diff --git a/excel/Products.xls b/excel/Products.xls index dd861219c45286dd50808563aae0aaad61767bec..e32eb73e7d38ec6ff0a76762bf6e28fd6cd33e35 100644 GIT binary patch delta 1026 zcmYk5O>0v@6o${-+%`5%dlNtIjTxJ?bWtG`s-jJ_F^y2QexV5BS2eNCB2utavT~6u zT?j&txDRd=H|oW;xKPARmoEGf;zAIl=sCl9CRyB?0`wjZ=R z4{5QHqzdWTe3YXL*uFzNGi*UYsl*&7hf-&$RfJsZ^lmQ$Q zQbhAY9#L5+VM%$zFm5dD3yh&+TLG})xDXqrnJ$|uD^AEJUqoBVPzJCd#G0xQYaFqq zimxJFI%ykOb8JnB`;NF@!yl2JShS7Zre7E0ejR6WSJe_e%IVT+yR+By&IobutPp#r z@ncSRm+jg<(?2J~eMj7PH24f5O$2b>&V|NuL5MAm*y6}o{$DpTnu~TYGMY<5tZ~E| zN9HN8zyE#ZhVAEp8#jdpugi}Xz%9F{%{jO6X&J9g)Q*|{skH)sg4zkxsV zy4$pC6Q+Mpi2IJX?`ZHo1)2z8)y@@+Wle}Jj@aVJSkhGe2B+XF{bR4=6|M2Ue*U)6 GQ~vVf5Z{xU;XAli$oaXC^amYkq6?q9YZvwuffok2!&@&6xC1h~;g8}U28HXc0{wKq9RLL?OR4Onvm88K(a;y%sO44#nNm>G34#$QeKauzo_3m2Xgu{uLtAv)8lC-pG zb>#BW&P5D`%WFi(epZK$lAK{tNz#er42$%8#7`|n$8gxKt0ewJ;_p(c?l(?HM>Y7* zD2YFj_!IR$P>mA~XJf7wTFxm+%XxZJ_xziDuD^0u;>u`vtE=>E)Nd}wIUlmulq7py zNluWc_m;=l9VfQ)ugO@pmX&tRLfIxU<|bL2%}Yj- z7Ht>zgy6y^d>E4uDhLEZJFrb0kT_IA2oMO4o5W>YcHWW881H*|e)f}dA(E5$^Y`BS z`SWKd8{LhYk#GNrMsF0{$iOpKjt+k`Xz$w#0Q<=H64~~XO(NR?vK=JbzjqhkjocfW z-WJuy+~Vkw;nL8(2*CRN_UPt-dntC%9gJOc%pCybXa5IZ%#_;wj}aJ zk>g6@R9w-f5;USsnYg1UG^QlFE!<0rqyO*VWA$~bZ7tX99jj@rTDIMAJZ@ZCvfAC% zwYD_VTDBX~!dkc9mdcIhid1e{wc%b765{|blA2=a55hxQE6!Bh&YP8ee?T*&ZDSl^hv^XEXyMF~C@&PfY6*OZJJS z`o#1;F$2H}Eo}BlO!tXp`oyw*V!1xCJdfQUj~^e6OuKLD(&X0p!a#HOpiV6{ra_BK#K!qraY%M;f<5d_SkzIUz@Kn^msZ6r*Ui}=e zfT|!=dqO_l4l?=MoHN1}|N6IR5zj{j#9v_9*p@y%5yB^ec!%l}RDY6B5Y#7p{qMJ^ zKH-y1@(9X#lRx(Sb8m_*MfSwxF(cd6S_$A z@#j9Hc+JPd;lfjgcr>ARHClRd-vO3Z1Jo~bj;G)H>j7IF@l}?McX|wJEIS#(CprER z=_H)rNecR;pilbxhaXaXGN6~~1WAfN!2wwM8NP@3I_G$Jc=!h!JL-^xi!2?VNikSq z=_#(?WL=-)`ocs{pQ89xK0eqtDIb6Pdx}r___1FoAO#LKPJ>T?`b&Hd^_Mw^>9_8D z@+s~56zvVL0ci;-2AgI@Uz4jy3>%M;TF4gO_^d4TPedFPE+BY6v z_qv|rb%rPRKehq3o3A%QdLyJaXz9ssAsZjW8$N!s*Efcb|KS^oH+p!oKARv|dPC3~ zA-y4#9)FHv&?N78%bFp)8N!`kHTO<&J`ZcJYflT>dCr8kArn-t&T9M(6F zK8V}2Z%m56N{*AY9l#$>U!M-?(;
b<9BTEM3{{^RfV6tNy@AHPwg_;dhIo_}dU zpBD6Kuk>7>4(b7a;eC82gwKTV8H%6oojqh6L7(Azc=9>z`i!r~$0gxp0(#sF_Dx2> zXF~XlfXBZgP7K~5A6TetNT20;Dc*bFWO?HtB}?&bKHmSwFhTLz0DgkvvjRQ~+wuA5 z-LqM$@9^oo$E9(5H*K7(pvON=K0X)1=R)|LQ2HFjJ6*P1&M!Ud`kb%dI8XICL7x*! zpA+youk_&Ia{?a!-BG+lOP>$v^C5j+==wa>uQ7a{<2Ua7OiQ2l@lc@nynxR$Jh}Vu mO6CQ9KBUic{R21(@*aRQQFr6WqO4FFtJZ!$zlArF>o^DCN_Ikrf-~+9l5pGAI_t3f;f diff --git a/src/main/kotlin/com/restapi/controllers/Entities.kt b/src/main/kotlin/com/restapi/controllers/Entities.kt index eb497ae..5e28adf 100644 --- a/src/main/kotlin/com/restapi/controllers/Entities.kt +++ b/src/main/kotlin/com/restapi/controllers/Entities.kt @@ -909,26 +909,33 @@ object PaymentCtrl { fun create(ctx: Context) { val pmt = ctx.bodyAsClass(Payment::class.java) //update the status of invoices pertaining to payment.vendor - + val vendors: List? = pmt.vendor?.let { listOf(it.sysPk) } val invoices = searchInvoices( - CommonFilters(sortBy = "date", sortAsc = true), - InvoiceFilters(status = InvoiceStatus.PAID_NONE) + CommonFilters(sortBy = "date", sortAsc = true, vendor = vendors), + InvoiceFilters(status = InvoiceStatus.PAID_FULL) ) - println(invoices) +// println(invoices) + //pmt.invoicesAffected = mutableMapOf() + var totalAmount = pmt.amount + var totalDeduct = 0.0 for (invoice in invoices) { - val deduct = Math.min(pmt.amount, invoice.totalAmount) + val deduct = Math.min(totalAmount, invoice.totalAmount) invoice.totalAmount -= deduct - pmt.amount -= deduct + totalDeduct += deduct + totalAmount -= deduct if (invoice.totalAmount <= 0.0) { invoice.status = InvoiceStatus.PAID_FULL } else { invoice.status = InvoiceStatus.PAID_SOME } + //println(invoice) database.update(invoice) - pmt.invoicesAffected?.toMutableMap()?.put(invoice.sysPk, deduct) - if (pmt.amount <= 0.0) break + pmt.invoicesAffected?.put(invoice.sysPk, deduct) + println(pmt.invoicesAffected) + if (totalAmount <= 0.0) break } - pmt.excessAmount = pmt.amount + pmt.amountDeducted = totalDeduct + pmt.excessAmount = pmt.amount - pmt.amountDeducted!! database.save(pmt) ctx.json(pmt).status(HttpStatus.CREATED) } @@ -942,6 +949,7 @@ object PaymentCtrl { val inv = database.find(Invoice::class.java, entry.key) ?: throw NotFoundResponse("No invoice found for $entry.key") inv.totalAmount += entry.value + inv.status = InvoiceStatus.PAID_SOME database.update(inv) } database.delete(pmt) @@ -960,10 +968,10 @@ object PaymentCtrl { fun getAll(ctx: Context) { val filters = ctx.bodyAsClass() val payments = searchPayments(filters.common, filters.paymentFilters) - println(payments) + // println(payments) val excel = ctx.queryParam("excel") if (excel !== null) { -// exportPayments(payments) + exportPayments(payments) val inputStream = FileInputStream("./excel/Payments.xls") ctx.result(inputStream).status(HttpStatus.OK) } else { @@ -1003,7 +1011,7 @@ object InvoiceCtrl { val invoices = searchInvoices(filters.common, filters.invoiceFilters) val excel = ctx.queryParam("excel") if (excel !== null) { -// exportPayments(payments) + exportInvoices(invoices) val inputStream = FileInputStream("./excel/Invoices.xls") ctx.result(inputStream).status(HttpStatus.OK) } else { diff --git a/src/main/kotlin/com/restapi/controllers/Excel.kt b/src/main/kotlin/com/restapi/controllers/Excel.kt index b518e40..a33dfc6 100644 --- a/src/main/kotlin/com/restapi/controllers/Excel.kt +++ b/src/main/kotlin/com/restapi/controllers/Excel.kt @@ -101,6 +101,7 @@ enum class FileType { enum class EnumFor { UOM, DocType } + fun saveExcelFileLocally(fileName: String, wb: Workbook) { val path = "./excel/" val out = FileOutputStream(path + fileName) @@ -245,7 +246,17 @@ fun exportVendors(vendors: List) { val sh = wb.createSheet() val headers: List = - listOf("No.", "Name", "MSME", "GST Number", "Address", "Rating", "Contact Name", "Contact Email", "Contact Mobile") + listOf( + "No.", + "Name", + "MSME", + "GST Number", + "Address", + "Rating", + "Contact Name", + "Contact Email", + "Contact Mobile" + ) createHeaderRow(headers, sh, wb) val totalCols = headers.size @@ -338,7 +349,7 @@ fun exportPos(pos: List) { saveExcelFileLocally("Pos.xls", wb) } -fun exportIncomingInventory(tickets : List) { +fun exportIncomingInventory(tickets: List) { val wb = HSSFWorkbook() val sh = wb.createSheet() @@ -379,7 +390,7 @@ fun exportIncomingInventory(tickets : List) { saveExcelFileLocally("IncomingInventory.xls", wb) } -fun exportOutgoingInventory(tickets : List) { +fun exportOutgoingInventory(tickets: List) { val wb = HSSFWorkbook() val sh = wb.createSheet() @@ -417,6 +428,73 @@ fun exportOutgoingInventory(tickets : List) { } saveExcelFileLocally("OutgoingInventory.xls", wb) } + +fun exportPayments(payments: List) { + val wb = HSSFWorkbook() + val sh = wb.createSheet() + + val headers: List = listOf("Reference Number", "Vendor", "Amount Paid", "Amount Deducted", "Excess Amount") + createHeaderRow(headers, sh, wb) + + var rowCnt = 1 + + for (pmt in payments) { + val row = sh.createRow(rowCnt++) + var i = 0 + row.createCell(i++).setCellValue(pmt.refNumber) + row.createCell(i++).setCellValue(pmt.vendor?.name) + row.createCell(i++).setCellValue(pmt.amount) + pmt.amountDeducted?.let { row.createCell(i++).setCellValue(it) } + pmt.excessAmount?.let { row.createCell(i++).setCellValue(it) } + } + saveExcelFileLocally("Payments.xls", wb) +} + +fun exportInvoices(invoices: List) { + val wb = HSSFWorkbook() + val sh = wb.createSheet() + + val headers: List = listOf( + "Number", + "Date", + "Reference PO", + "Status", + "Vendor Name", + "Vendor Address", + "Product Id", + "Product Name", + "Unit Price", + "Quantity", + "Total Amount" + ) + createHeaderRow(headers, sh, wb) + + var rowCnt = 1 + for (invoice in invoices) { + val prodCnt = invoice.products?.size + + for (j in 0..? = null + var invoicesAffected: MutableMap? = mutableMapOf() + @ManyToOne var vendor: Vendor? = null } \ No newline at end of file diff --git a/src/main/resources/dbmigration/1.14.sql b/src/main/resources/dbmigration/1.14.sql new file mode 100644 index 0000000..ee8d733 --- /dev/null +++ b/src/main/resources/dbmigration/1.14.sql @@ -0,0 +1,2 @@ +-- apply alter tables +alter table payment add column if not exists amount_deducted float; diff --git a/src/main/resources/dbmigration/model/1.14.model.xml b/src/main/resources/dbmigration/model/1.14.model.xml new file mode 100644 index 0000000..910acb6 --- /dev/null +++ b/src/main/resources/dbmigration/model/1.14.model.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file