<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: anoop p</title>
    <description>The latest articles on DEV Community by anoop p (@anoop_p_22f715057ac8b3901).</description>
    <link>https://dev.to/anoop_p_22f715057ac8b3901</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2595876%2Fa1bf0c1b-a8c8-4700-9678-839660451a53.png</url>
      <title>DEV Community: anoop p</title>
      <link>https://dev.to/anoop_p_22f715057ac8b3901</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anoop_p_22f715057ac8b3901"/>
    <language>en</language>
    <item>
      <title>What I Shipped in April Building Invoiso(v4.0.5)</title>
      <dc:creator>anoop p</dc:creator>
      <pubDate>Sat, 02 May 2026 16:44:09 +0000</pubDate>
      <link>https://dev.to/anoop_p_22f715057ac8b3901/what-i-shipped-in-april-building-invoiso-4gob</link>
      <guid>https://dev.to/anoop_p_22f715057ac8b3901/what-i-shipped-in-april-building-invoiso-4gob</guid>
      <description>&lt;p&gt;April was one of the busiest months so far while building &lt;strong&gt;Invoiso&lt;/strong&gt;, a free offline invoice and billing tool for Windows and Linux.&lt;/p&gt;

&lt;p&gt;This month was less about one big headline feature and more about making the app work better for real businesses: due dates, quotations, customer imports, product imports, bank details, better PDF downloads, and a lot of layout and reliability fixes.&lt;/p&gt;

&lt;h3&gt;
  
  
  All Changes Shipped in April 2026
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/Anooppandikashala/invoiso" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://invoiso.co.in/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; · &lt;a href="https://invoiso.co.in/download.html" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  The Focus This Month
&lt;/h3&gt;

&lt;p&gt;The focus for April was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better invoice follow-up with due dates and overdue visibility&lt;/li&gt;
&lt;li&gt;Cleaner separation between invoices and quotations&lt;/li&gt;
&lt;li&gt;More flexible payment details with UPI and bank accounts&lt;/li&gt;
&lt;li&gt;Faster data entry through CSV import/export&lt;/li&gt;
&lt;li&gt;Better support for service businesses and custom line items&lt;/li&gt;
&lt;li&gt;More reliable PDFs, exports, and layouts&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Multiple UPI Accounts
&lt;/h3&gt;

&lt;p&gt;UPI support is now more flexible.&lt;/p&gt;

&lt;p&gt;Instead of storing only one UPI ID, Invoiso now supports multiple UPI payment accounts in Settings.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add multiple UPI accounts&lt;/li&gt;
&lt;li&gt;Give each account a friendly label, like "HDFC Bank"&lt;/li&gt;
&lt;li&gt;Mark one account as the default&lt;/li&gt;
&lt;li&gt;Select the UPI account while creating an invoice&lt;/li&gt;
&lt;li&gt;Print the selected UPI account QR code on the generated PDF&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is useful when a business accepts payments through different bank accounts or wants separate payment accounts for different invoice types.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bank Account Details on Invoices
&lt;/h3&gt;

&lt;p&gt;Along with UPI accounts, Invoiso now supports multiple bank accounts.&lt;/p&gt;

&lt;p&gt;Each bank account can store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Label&lt;/li&gt;
&lt;li&gt;Bank name&lt;/li&gt;
&lt;li&gt;Account number&lt;/li&gt;
&lt;li&gt;IFSC code&lt;/li&gt;
&lt;li&gt;Default account status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also a new &lt;strong&gt;Show Bank Details on Invoices&lt;/strong&gt; setting. When enabled, the selected bank account is printed on generated PDFs across all three templates: Classic, Modern, and Minimal.&lt;/p&gt;

&lt;p&gt;This makes invoices more complete for customers who prefer bank transfers instead of UPI payments.&lt;/p&gt;




&lt;h3&gt;
  
  
  Due Dates, Overdue Invoices, and Due Soon
&lt;/h3&gt;

&lt;p&gt;Due date support was a big part of the April work.&lt;/p&gt;

&lt;p&gt;Invoices now have an optional &lt;strong&gt;Due Date&lt;/strong&gt; field next to the existing Order Date. The due date can be cleared after selection and is printed on PDFs across all templates.&lt;/p&gt;

&lt;p&gt;The invoice list now shows both Order Date and Due Date in the date column. Unpaid overdue invoices are highlighted in red with an &lt;strong&gt;Overdue&lt;/strong&gt; badge, and invoices due today are highlighted in amber with a &lt;strong&gt;Due Today&lt;/strong&gt; badge.&lt;/p&gt;

&lt;p&gt;There are also new due date filters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All Dues&lt;/li&gt;
&lt;li&gt;Overdue&lt;/li&gt;
&lt;li&gt;Due Today&lt;/li&gt;
&lt;li&gt;Due This Week&lt;/li&gt;
&lt;li&gt;Due This Month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dashboard also became more useful for follow-up work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Due Soon&lt;/strong&gt; shows unpaid or partial invoices due today or tomorrow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overdue Invoices&lt;/strong&gt; shows unpaid invoices past their due date&lt;/li&gt;
&lt;li&gt;Quick actions are available for view, PDF preview, and record payment&lt;/li&gt;
&lt;li&gt;Dashboard stats now show outstanding balance, collected revenue, overdue counts, and out-of-stock counts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes Invoiso better for day-to-day invoice tracking, not just invoice generation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Separate Quotations Screen
&lt;/h3&gt;

&lt;p&gt;Invoices and quotations now have separate screens.&lt;/p&gt;

&lt;p&gt;There is a dedicated &lt;strong&gt;Quotations&lt;/strong&gt; entry in the navigation rail, and quotation management has its own table. Since invoices and quotations are now separated, the old Type column was removed from both screens.&lt;/p&gt;

&lt;p&gt;The quotations screen also hides payment-specific actions and columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status column&lt;/li&gt;
&lt;li&gt;Outstanding balance column&lt;/li&gt;
&lt;li&gt;Apply payment button&lt;/li&gt;
&lt;li&gt;Hide paid toggle&lt;/li&gt;
&lt;li&gt;Due date filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The screen title now changes based on context: &lt;strong&gt;Invoice Management&lt;/strong&gt; or &lt;strong&gt;Quotation Management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This makes quotation workflows much cleaner.&lt;/p&gt;




&lt;h3&gt;
  
  
  Customer Management Improvements
&lt;/h3&gt;

&lt;p&gt;Customer management got a major upgrade with CSV import.&lt;/p&gt;

&lt;p&gt;You can now bulk import customers from a CSV file using strict headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name, email, phone, address, business_name, tax_number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The import flow includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import rules dialog&lt;/li&gt;
&lt;li&gt;Downloadable sample CSV&lt;/li&gt;
&lt;li&gt;200-row import limit&lt;/li&gt;
&lt;li&gt;Duplicate detection by email or phone&lt;/li&gt;
&lt;li&gt;Preview dialog for valid rows, duplicates, and errors&lt;/li&gt;
&lt;li&gt;Per-row Skip / Overwrite controls&lt;/li&gt;
&lt;li&gt;Overwrite All / Skip All shortcuts&lt;/li&gt;
&lt;li&gt;BOM handling for Excel-saved CSV files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Customer CSV export was also updated to match the import format, with all fields double-quoted for better round-trip compatibility.&lt;/p&gt;

&lt;p&gt;There is also an admin-only &lt;strong&gt;Delete All Customers&lt;/strong&gt; action with a confirmation dialog.&lt;/p&gt;

&lt;p&gt;Another important addition is &lt;strong&gt;Business Name&lt;/strong&gt;. It now appears in the customer form, CSV import/export, invoice customer details, and generated PDFs below the customer name.&lt;/p&gt;




&lt;h3&gt;
  
  
  Save Customer While Creating an Invoice
&lt;/h3&gt;

&lt;p&gt;The create invoice screen now lets you save customer details directly from the Customer Details card.&lt;/p&gt;

&lt;p&gt;If the customer does not exist, they are added to the customer list without leaving the invoice screen.&lt;/p&gt;

&lt;p&gt;If a customer with the same phone number already exists, Invoiso asks whether to update the existing record or keep it unchanged.&lt;/p&gt;

&lt;p&gt;Once saved, the customer is automatically selected for the invoice and the button changes to &lt;strong&gt;Saved&lt;/strong&gt; to prevent duplicates.&lt;/p&gt;

&lt;p&gt;This removes one of the small but annoying context switches while creating invoices.&lt;/p&gt;




&lt;h3&gt;
  
  
  Product Management CSV Import / Export
&lt;/h3&gt;

&lt;p&gt;Product management now supports CSV import and export too.&lt;/p&gt;

&lt;p&gt;Products can be imported with these strict headers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name, description, price, tax_rate, hsn_code, stock, type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The product import flow includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import rules dialog&lt;/li&gt;
&lt;li&gt;Downloadable sample CSV&lt;/li&gt;
&lt;li&gt;500-row import limit&lt;/li&gt;
&lt;li&gt;Duplicate detection by product name&lt;/li&gt;
&lt;li&gt;Per-row Skip / Overwrite controls&lt;/li&gt;
&lt;li&gt;Overwrite All / Skip All shortcuts&lt;/li&gt;
&lt;li&gt;BOM handling for Excel compatibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Products can also be exported to CSV, and selected products can be exported too.&lt;/p&gt;

&lt;p&gt;There is also an admin-only &lt;strong&gt;Delete All Products&lt;/strong&gt; action.&lt;/p&gt;




&lt;h3&gt;
  
  
  Product and Service Support
&lt;/h3&gt;

&lt;p&gt;Products now have a &lt;strong&gt;Type&lt;/strong&gt; field:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product&lt;/li&gt;
&lt;li&gt;Service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The type is displayed in the product list and carried through to invoice line items.&lt;/p&gt;

&lt;p&gt;This also connects with invoice settings. Businesses can now decide how quantity should behave for their use case.&lt;/p&gt;




&lt;h3&gt;
  
  
  Show Quantity Toggle
&lt;/h3&gt;

&lt;p&gt;There is a new &lt;strong&gt;Show Quantity&lt;/strong&gt; toggle in Invoice Settings.&lt;/p&gt;

&lt;p&gt;When disabled, the Qty column is hidden from the invoice item table on screen and from generated PDFs.&lt;/p&gt;

&lt;p&gt;This is helpful for service businesses that bill by description or scope instead of quantity.&lt;/p&gt;




&lt;h3&gt;
  
  
  Fractional Quantities
&lt;/h3&gt;

&lt;p&gt;Quantities can now support decimal values.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1.5 hours&lt;/li&gt;
&lt;li&gt;0.5 kg&lt;/li&gt;
&lt;li&gt;2.25 units&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a new &lt;strong&gt;Allow Fractional Quantities&lt;/strong&gt; toggle in Invoice Settings. It is off by default, so businesses selling physical goods can keep the simpler whole-number flow.&lt;/p&gt;

&lt;p&gt;When enabled, quantity inputs accept decimal values and display cleanly: whole numbers appear as &lt;code&gt;2&lt;/code&gt;, while fractional values appear only when needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Discount Per Unit
&lt;/h3&gt;

&lt;p&gt;Line item discounts are now more flexible.&lt;/p&gt;

&lt;p&gt;Each invoice item has a &lt;strong&gt;Discount per unit&lt;/strong&gt; toggle.&lt;/p&gt;

&lt;p&gt;When disabled, the discount is applied to the line total:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(price x quantity) - discount
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When enabled, the discount is applied before multiplying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(price - discount) x quantity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existing invoices stay backward compatible and continue using the original behavior.&lt;/p&gt;




&lt;h3&gt;
  
  
  Additional Costs
&lt;/h3&gt;

&lt;p&gt;Invoices now support additional invoice-level costs.&lt;/p&gt;

&lt;p&gt;There is a collapsible &lt;strong&gt;Additional Costs&lt;/strong&gt; section where you can add rows such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shipping&lt;/li&gt;
&lt;li&gt;Packaging&lt;/li&gt;
&lt;li&gt;Handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additional costs are added after tax calculation and are shown separately in the invoice totals panel and generated PDFs.&lt;/p&gt;

&lt;p&gt;Multiple cost rows are supported, and the section header shows a count badge when costs are added.&lt;/p&gt;




&lt;h3&gt;
  
  
  Custom Items and Price Overrides
&lt;/h3&gt;

&lt;p&gt;Invoice line items are now much more flexible.&lt;/p&gt;

&lt;p&gt;You can override the unit price for a product directly inside the add/edit item dialog. Overridden prices are highlighted in the invoice item list with an asterisk.&lt;/p&gt;

&lt;p&gt;There is also a &lt;strong&gt;Custom Item&lt;/strong&gt; button in the product search area. This lets you add one-off items without creating a product first.&lt;/p&gt;

&lt;p&gt;Custom items support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom name&lt;/li&gt;
&lt;li&gt;Custom price&lt;/li&gt;
&lt;li&gt;Custom tax rate when per-item tax mode is enabled&lt;/li&gt;
&lt;li&gt;Persistence when editing invoices&lt;/li&gt;
&lt;li&gt;Correct PDF and CSV export output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Custom items can also be saved back into the product catalogue directly from the invoice screen.&lt;/p&gt;




&lt;h3&gt;
  
  
  GST, Tax Labels, and Country Support
&lt;/h3&gt;

&lt;p&gt;Invoiso now has better support for businesses that do not need GST fields.&lt;/p&gt;

&lt;p&gt;There is a &lt;strong&gt;Show GST Fields&lt;/strong&gt; toggle in Invoice Settings. When disabled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GSTIN field is hidden from the invoice screen&lt;/li&gt;
&lt;li&gt;GSTIN is excluded from exports and PDFs&lt;/li&gt;
&lt;li&gt;HSN Code is hidden from generated PDFs&lt;/li&gt;
&lt;li&gt;Tax row is hidden from PDFs&lt;/li&gt;
&lt;li&gt;Enable Tax toggle is hidden and tax is automatically disabled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Company Info also now has a &lt;strong&gt;Country&lt;/strong&gt; field with searchable autocomplete covering 195 countries. It defaults to India.&lt;/p&gt;

&lt;p&gt;The tax label is dynamic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;India or blank country: &lt;code&gt;GSTIN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Other countries: &lt;code&gt;Tax/VAT No&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This applies across the invoice form, all PDF templates, and payment receipts.&lt;/p&gt;




&lt;h3&gt;
  
  
  PDF View, Download, and Bulk Export
&lt;/h3&gt;

&lt;p&gt;PDF handling improved a lot this month.&lt;/p&gt;

&lt;p&gt;The PDF preview window now has &lt;strong&gt;Print&lt;/strong&gt; and &lt;strong&gt;Download&lt;/strong&gt; buttons in the toolbar. Download opens a file picker so the user can choose exactly where to save the PDF.&lt;/p&gt;

&lt;p&gt;Downloaded files now use a clearer filename format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inv-{number}-{customerfullname}-{date}.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inv-42-john_doe-20260402.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The download button is also available from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invoice list&lt;/li&gt;
&lt;li&gt;Dashboard recent invoices&lt;/li&gt;
&lt;li&gt;Create/edit invoice screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bulk PDF downloads also improved. Selecting multiple invoices and clicking &lt;strong&gt;Download PDFs&lt;/strong&gt; now asks whether to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Save PDFs to a folder&lt;/li&gt;
&lt;li&gt;Save all PDFs as a ZIP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ZIP option uses a filename like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoices_YYYYMMDD.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A progress dialog shows generation progress for both folder and ZIP export modes.&lt;/p&gt;




&lt;h3&gt;
  
  
  Company Info and Invoice Customization
&lt;/h3&gt;

&lt;p&gt;Several invoice customization options were added or improved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Company website now prints on PDFs when set&lt;/li&gt;
&lt;li&gt;Company phone supports multiple numbers separated by commas&lt;/li&gt;
&lt;li&gt;Phone input supports international formats with &lt;code&gt;+&lt;/code&gt;, spaces, and parentheses&lt;/li&gt;
&lt;li&gt;Country, phone, and email fields are grouped into a cleaner row in Company Info&lt;/li&gt;
&lt;li&gt;Company logo size can be set to Small, Medium, or Large&lt;/li&gt;
&lt;li&gt;Logo size applies to all PDF templates&lt;/li&gt;
&lt;li&gt;Invoice details card is wider for better readability&lt;/li&gt;
&lt;li&gt;Customer Details form was reorganized into two rows of three columns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sidebar logo also improved: the expanded sidebar shows the full horizontal logo, while the collapsed sidebar shows the square app icon.&lt;/p&gt;




&lt;h3&gt;
  
  
  CSV Export Improvements
&lt;/h3&gt;

&lt;p&gt;CSV export received several fixes and quality-of-life improvements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invoice CSV export is sorted by invoice number in ascending order&lt;/li&gt;
&lt;li&gt;Export now opens a filter dialog before exporting&lt;/li&gt;
&lt;li&gt;You can export all records or choose a date range&lt;/li&gt;
&lt;li&gt;Validation prevents exporting when the To date is before the From date&lt;/li&gt;
&lt;li&gt;Invoice screen exports only invoices&lt;/li&gt;
&lt;li&gt;Quotation screen exports only quotations&lt;/li&gt;
&lt;li&gt;CSV filenames and first-column headers now reflect invoice or quotation type&lt;/li&gt;
&lt;li&gt;Due Date column is included&lt;/li&gt;
&lt;li&gt;UPI/payment account column is included&lt;/li&gt;
&lt;li&gt;UTF-8 BOM is added so Excel and LibreOffice read files correctly&lt;/li&gt;
&lt;li&gt;Unicode multiplication symbol was replaced with plain &lt;code&gt;x&lt;/code&gt; to avoid encoding issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes exports more predictable and safer for spreadsheet usage.&lt;/p&gt;




&lt;h3&gt;
  
  
  Dashboard Improvements
&lt;/h3&gt;

&lt;p&gt;The dashboard is becoming more operational.&lt;/p&gt;

&lt;p&gt;New and improved sections include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total Revenue Collected&lt;/li&gt;
&lt;li&gt;Outstanding Balance&lt;/li&gt;
&lt;li&gt;Due Soon&lt;/li&gt;
&lt;li&gt;Overdue Invoices&lt;/li&gt;
&lt;li&gt;Out of Stock&lt;/li&gt;
&lt;li&gt;Reports coming soon placeholder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dashboard content is now capped at a cleaner max width and centered on large screens.&lt;/p&gt;




&lt;h3&gt;
  
  
  Layout and Shared Widget Work
&lt;/h3&gt;

&lt;p&gt;April also included a lot of layout cleanup.&lt;/p&gt;

&lt;p&gt;New layout width constants were added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;maxWidthNarrow = 900&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;maxWidthNormal = 1200&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;maxWidthWide = 1700&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are used across settings, dashboard, customer, product, invoice list, and create invoice screens to keep large displays readable.&lt;/p&gt;

&lt;p&gt;The reusable &lt;code&gt;CustomerInfoButton&lt;/code&gt; widget was also extracted and is now shared by the invoice list and dashboard Due Soon section.&lt;/p&gt;




&lt;h3&gt;
  
  
  Smaller Improvements
&lt;/h3&gt;

&lt;p&gt;Other improvements shipped this month:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Invoice shortcut appears in the AppBar while editing an invoice&lt;/li&gt;
&lt;li&gt;Invoice number info card explains how invoice numbers are generated&lt;/li&gt;
&lt;li&gt;Invoice number tooltip shows the same explanation on hover&lt;/li&gt;
&lt;li&gt;Tax rate segment selector now has individual tooltips&lt;/li&gt;
&lt;li&gt;PDF action tooltip renamed to &lt;strong&gt;PDF View / Download&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;South African Rand (ZAR) added to supported currencies&lt;/li&gt;
&lt;li&gt;Product/service type label removed from generated PDFs&lt;/li&gt;
&lt;li&gt;Error SnackBars now include a copy icon so error messages can be copied easily&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Bug Fixes
&lt;/h3&gt;

&lt;p&gt;This month also included many bug fixes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fixed Additional Notes not saving or displaying correctly&lt;/li&gt;
&lt;li&gt;Fixed discount calculation issues in certain scenarios&lt;/li&gt;
&lt;li&gt;Fixed New Invoice from edit mode not fully resetting the form&lt;/li&gt;
&lt;li&gt;Fixed layout overflow in invoice and quotation customer columns&lt;/li&gt;
&lt;li&gt;Fixed sparse invoice lists being vertically centered instead of top-aligned&lt;/li&gt;
&lt;li&gt;Fixed Enable Tax toggle showing when GST fields were disabled&lt;/li&gt;
&lt;li&gt;Fixed dashboard recent invoice layout issues&lt;/li&gt;
&lt;li&gt;Fixed due date row overflow on smaller screens&lt;/li&gt;
&lt;li&gt;Fixed invoice list date column overflow&lt;/li&gt;
&lt;li&gt;Fixed invoice/quotation switching not reloading the correct data&lt;/li&gt;
&lt;li&gt;Fixed UPI dropdown layout crash from unbounded width constraints&lt;/li&gt;
&lt;li&gt;Fixed CSV garbled characters in Excel and LibreOffice&lt;/li&gt;
&lt;li&gt;Fixed missing Due Date and UPI/payment account columns in CSV export&lt;/li&gt;
&lt;li&gt;Fixed invoice totals row overflow on narrow screens&lt;/li&gt;
&lt;li&gt;Fixed invoice type dropdown overflow&lt;/li&gt;
&lt;li&gt;Fixed collapsed sidebar chevron overlapping the logo&lt;/li&gt;
&lt;li&gt;Fixed discount per unit not persisting when editing invoices&lt;/li&gt;
&lt;li&gt;Fixed Total Due disappearing from PDFs immediately after updating an invoice&lt;/li&gt;
&lt;li&gt;Fixed invoice notes not appearing consistently on newly created invoices&lt;/li&gt;
&lt;li&gt;Fixed Amount Paid and Amount Due row overflow&lt;/li&gt;
&lt;li&gt;Fixed saving custom items to the product catalogue from the invoice screen&lt;/li&gt;
&lt;li&gt;Fixed tax row printing on PDFs when GST fields were disabled&lt;/li&gt;
&lt;li&gt;Fixed bulk PDF filenames using the old &lt;code&gt;Invoice_00000001.pdf&lt;/code&gt; format&lt;/li&gt;
&lt;li&gt;Fixed startup crash from duplicate DB migration columns&lt;/li&gt;
&lt;li&gt;Fixed DB migration ordering for v16 through v20&lt;/li&gt;
&lt;li&gt;Fixed PDF preview crash when bank details were included&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not glamorous work, but this is the kind of polish that makes the app feel more dependable.&lt;/p&gt;




&lt;h3&gt;
  
  
  What I Learned
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Follow-up workflows matter.&lt;/strong&gt;&lt;br&gt;
Due dates, overdue indicators, and due-soon cards make the app more useful after an invoice is created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import/export needs to be strict.&lt;/strong&gt;&lt;br&gt;
CSV import sounds simple, but real-world files need validation, duplicate handling, sample files, row limits, and Excel compatibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small layout bugs add up.&lt;/strong&gt;&lt;br&gt;
Many fixes this month were about overflow, width constraints, and screen-specific UI. These are easy to ignore during development but very visible to users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Invoices and quotations deserve separate workflows.&lt;/strong&gt;&lt;br&gt;
Keeping them in one table worked for a while, but separating them made the product easier to understand.&lt;/p&gt;




&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Next, I am exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better reporting and analytics&lt;/li&gt;
&lt;li&gt;More invoice customization&lt;/li&gt;
&lt;li&gt;Better payment workflow improvements&lt;/li&gt;
&lt;li&gt;More polish around import/export flows&lt;/li&gt;
&lt;li&gt;Continued Linux and Windows desktop stability improvements&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Feedback Welcome
&lt;/h3&gt;

&lt;p&gt;If you have tried Invoiso or have any thoughts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What workflow still feels slow?&lt;/li&gt;
&lt;li&gt;What should be easier?&lt;/li&gt;
&lt;li&gt;What feature would make Invoiso more useful for your business?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add a comment below or open an issue on &lt;a href="https://github.com/Anooppandikashala/invoiso/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Invoiso is free, open source, and runs entirely offline. No account required. No data leaves your device.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading. More updates soon.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What I Shipped This Month Building Invoiso (v3.4.2)</title>
      <dc:creator>anoop p</dc:creator>
      <pubDate>Tue, 31 Mar 2026 13:50:27 +0000</pubDate>
      <link>https://dev.to/anoop_p_22f715057ac8b3901/what-i-shipped-this-month-building-invoiso-v342-31he</link>
      <guid>https://dev.to/anoop_p_22f715057ac8b3901/what-i-shipped-this-month-building-invoiso-v342-31he</guid>
      <description>&lt;p&gt;One of the best things about working on &lt;strong&gt;Invoiso&lt;/strong&gt;, a free offline invoice and billing tool available for Windows and Linux operating systems, has been “building in public.” This month has been particularly fruitful as a mix of long-pending features, quality-of-life enhancements, and critical bug fixes were included.&lt;/p&gt;

&lt;h3&gt;
  
  
  All Changes in &lt;strong&gt;v3.4.2&lt;/strong&gt; 👇
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 &lt;a href="https://github.com/Anooppandikashala/invoiso" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://invoiso.co.in/" rel="noopener noreferrer"&gt;Website&lt;/a&gt; · &lt;a href="https://invoiso.co.in/download.html" rel="noopener noreferrer"&gt;Download&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  💡 The Focus This Month
&lt;/h3&gt;

&lt;p&gt;This release is all about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;More flexibility&lt;/strong&gt; in invoicing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better real-world usage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smoother payments and workflows&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🌍 Multi-Currency Support
&lt;/h3&gt;

&lt;p&gt;One of the most requested features is finally here.&lt;/p&gt;

&lt;p&gt;Create invoices in different currencies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;INR · USD · EUR · GBP · JPY · AED · SGD · AUD · CAD · JMD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each invoice &lt;strong&gt;locks in the currency at creation time&lt;/strong&gt;, maintaining historical data’s accuracy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is multi-currency support important?&lt;/strong&gt;&lt;br&gt;
If you work with clients across borders, you know how annoying currency conversions can be.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧾 Per Item Tax Rates
&lt;/h3&gt;

&lt;p&gt;Tax rate is now set per item.&lt;/p&gt;

&lt;p&gt;Tax rate is no longer set at the invoice level.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is per item tax rate useful?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mixed GST items&lt;/li&gt;
&lt;li&gt;Different tax rates for different service/product types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes things more similar to real-world usage.&lt;/p&gt;




&lt;h3&gt;
  
  
  💸 UPI QR Code on Invoices
&lt;/h3&gt;

&lt;p&gt;A significant feature update for users in India.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter your UPI ID in settings&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;QR code is automatically added&lt;/strong&gt; on every invoice you create in PDF format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clients can also scan and pay instantly using GPay, PhonePe, or Paytm. There is no need to type anything or get confused.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔁 Invoice Cloning
&lt;/h3&gt;

&lt;p&gt;Creating similar invoices was a tedious task. This feature lets you clone an invoice and use it as a starting point.&lt;/p&gt;

&lt;p&gt;A small feature, a big time saver.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Bulk Actions
&lt;/h3&gt;

&lt;p&gt;You can select multiple invoices and perform actions on them in bulk.&lt;/p&gt;

&lt;p&gt;More efficiency, less clicks.&lt;/p&gt;




&lt;h3&gt;
  
  
  💳 Payment Tracking &amp;amp; Receipts
&lt;/h3&gt;

&lt;p&gt;This was a big feature.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mark invoices as &lt;strong&gt;Paid / Partially Paid / Unpaid&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Track payment history&lt;/li&gt;
&lt;li&gt;Generate downloadable &lt;strong&gt;PDF payment receipts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature alone makes Invoiso not just an invoice generator, but a basic invoicing system.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔐 Role-Based Access Control (RBAC)
&lt;/h3&gt;

&lt;p&gt;This feature is for those who work in teams.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set admin and user roles&lt;/li&gt;
&lt;li&gt;Set access level for each user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feature will pave the way for more user-based features.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧭 Invoice Type Indicator
&lt;/h3&gt;

&lt;p&gt;The invoice type is also visible on the invoice list and dashboard. There is no need to click on an invoice to know its type.&lt;/p&gt;

&lt;p&gt;A small feature, a big time saver.&lt;/p&gt;




&lt;h3&gt;
  
  
  🖥️ Ubuntu 24.04 LTS Support
&lt;/h3&gt;

&lt;p&gt;Linux users, rejoice! Builds are tested and working on &lt;strong&gt;Ubuntu 24.04 LTS&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 UI/UX Improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Redesigned: PDF Settings, Company Info, and Software Info screens&lt;/li&gt;
&lt;li&gt;Fixed: annoying bug where search fields lost focus on fast typing&lt;/li&gt;
&lt;li&gt;&lt;p&gt;General layout and visual polish on screens&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixed ₹ symbol rendering incorrectly in generated PDFs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixed database connection dropping after backup restore&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixed window resizing issues on Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updated Windows app icon (all sizes: 16, 32, 48, 256px)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📊 What I Learned
&lt;/h3&gt;

&lt;p&gt;Some observations and insights from this release cycle:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small UX issues matter more than missing features.&lt;/strong&gt;&lt;br&gt;
The search field focus bug was reported most. More than any missing feature. Fixing UX issues is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payments are core, not optional.&lt;/strong&gt;&lt;br&gt;
Tracking and receipts are a big part of any payment process. This is a game-changer for the product. Should have done this earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed of iteration &amp;gt; perfection.&lt;/strong&gt;&lt;br&gt;
Shipping is important. Consistency is key. Will improve and iterate soon. &lt;/p&gt;




&lt;h3&gt;
  
  
  🔮 What's Next?
&lt;/h3&gt;

&lt;p&gt;Exploring next for Invoiso:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improving &lt;strong&gt;reporting &amp;amp; analytics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Improving &lt;strong&gt;payment workflows&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Improving &lt;strong&gt;invoice customization options&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🙌 Feedback Welcome
&lt;/h3&gt;

&lt;p&gt;If you have tried Invoiso or have any thoughts on it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How are you using Invoiso?&lt;/li&gt;
&lt;li&gt;What is missing?&lt;/li&gt;
&lt;li&gt;What is clunky?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add a comment below or open an issue on &lt;a href="https://github.com/Anooppandikashala/invoiso/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I read all of them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Invoiso is free, open source, and runs entirely offline. No account required. No data leaves your device.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Thanks for reading! More updates soon! 🚀&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>buildinpublic</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I built a free Android soundboard that works with a External keyboard</title>
      <dc:creator>anoop p</dc:creator>
      <pubDate>Wed, 25 Mar 2026 11:29:40 +0000</pubDate>
      <link>https://dev.to/anoop_p_22f715057ac8b3901/i-built-a-free-android-soundboard-that-works-with-a-external-keyboard-25fi</link>
      <guid>https://dev.to/anoop_p_22f715057ac8b3901/i-built-a-free-android-soundboard-that-works-with-a-external-keyboard-25fi</guid>
      <description>&lt;p&gt;A few months ago I needed a simple soundboard for a live session. I wanted to trigger audio clips from a Bluetooth/External keyboard connected to my Android phone - just press a key, hear the sound, instantly.&lt;/p&gt;

&lt;p&gt;Every app I found was either subscription-based, required an account, or didn't support physical keyboards at all. So I built &lt;strong&gt;CTunes&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What CTunes does
&lt;/h3&gt;

&lt;p&gt;CTunes maps keyboard keys (A-Z and 0-9) to audio files on your device. Tap the on-screen button or press the physical key — the sound plays immediately.&lt;/p&gt;

&lt;p&gt;That's the whole pitch. &lt;strong&gt;36 keys. Any audio file. Zero lag.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Try it
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.anoop.myprojects.ctunes" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Play:&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anooppandikashala.github.io/ctunes.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;Landing page:&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love feedback — especially from anyone who uses soundboards for live performance, streaming, or teaching. What features would make this more useful for your workflow?&lt;/p&gt;

&lt;h4&gt;
  
  
  Core features
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key mapping&lt;/strong&gt; — pick any audio file from your device and assign it to a key
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual input&lt;/strong&gt; — works with on-screen taps and physical Bluetooth keyboards
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;18-color palette&lt;/strong&gt; — each key gets a unique color so you can read the board at a glance
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Import / Export&lt;/strong&gt; — your entire layout serialises to a single JSON file
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent storage&lt;/strong&gt; — mappings survive reboots and reinstalls via SQLite + &lt;code&gt;takePersistableUriPermission()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; — ad-supported, no subscription, no sign-in, works fully offline
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The tech stack
&lt;/h3&gt;

&lt;p&gt;CTunes is a native Android app written in &lt;strong&gt;Java&lt;/strong&gt; (yes, Java — not Kotlin). Here's how the main pieces fit together:&lt;/p&gt;

&lt;h4&gt;
  
  
  Architecture
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Single-module project, Activities only
&lt;/li&gt;
&lt;li&gt;No Fragments, no Navigation component
&lt;/li&gt;
&lt;li&gt;SQLite via a hand-rolled &lt;code&gt;SQLiteOpenHelper&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SharedPreferences&lt;/code&gt; for UI settings (grid size, column count, keyboard visibility)
&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Audio playback
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
java
// A new MediaPlayer is created per keypress
// The previous one is released first to avoid leaks
if (currentPlayer != null) {
    currentPlayer.release();
}
MediaPlayer mp = MediaPlayer.create(this, uri);
if (mp != null) {
    mp.setOnCompletionListener(MediaPlayer::release);
    mp.start();
    currentPlayer = mp;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>android</category>
      <category>showdev</category>
      <category>music</category>
      <category>soundboard</category>
    </item>
    <item>
      <title>I Built an Android App Because Android Kept Deleting My Clipboard</title>
      <dc:creator>anoop p</dc:creator>
      <pubDate>Thu, 19 Mar 2026 04:52:06 +0000</pubDate>
      <link>https://dev.to/anoop_p_22f715057ac8b3901/i-built-an-android-app-because-android-kept-deleting-my-clipboard-39o2</link>
      <guid>https://dev.to/anoop_p_22f715057ac8b3901/i-built-an-android-app-because-android-kept-deleting-my-clipboard-39o2</guid>
      <description>&lt;p&gt;Here's something that has happened to all of us.&lt;/p&gt;

&lt;p&gt;You copy a link. Then you copy someone's phone number. You go to paste the link - and it's gone. Replaced by the phone number. Android only remembers the last thing you copied. That's it. One item. Always.&lt;/p&gt;

&lt;p&gt;I kept running into this. Copying a piece of text, copying something else on top of it, then needing the first thing back with no way to get it. I'd go back to the original source, find it again, copy it again. Every time. It was a small annoyance, but it happened constantly.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://anooppandikashala.github.io/copyduo.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;CopyDuo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What CopyDuo Does
&lt;/h2&gt;

&lt;p&gt;CopyDuo runs quietly in the background and saves everything you copy - up to 50 items. Whenever you need something you copied earlier, you open the app, find it in the list, and tap it to copy it back to your clipboard.&lt;/p&gt;

&lt;p&gt;That's it. No accounts. No cloud. No internet connection. Your clipboard history stays on your device, private and instant.&lt;/p&gt;

&lt;p&gt;It also handles something I found genuinely annoying about other clipboard apps: duplicates. If you copy the same text twice, CopyDuo stores it only once. Your history stays clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Problem Is Harder to Solve Than It Looks
&lt;/h2&gt;

&lt;p&gt;When I started building this, I thought it would be straightforward - just listen for clipboard changes and save them to a local database. Simple, right?&lt;/p&gt;

&lt;p&gt;Not quite.&lt;/p&gt;

&lt;h3&gt;
  
  
  Android 12 Made Background Services Much Harder
&lt;/h3&gt;

&lt;p&gt;To capture clipboard items when the app isn't open, I needed a background service - a piece of code that keeps running even when you're not actively using the app. On older Android versions, this was manageable.&lt;/p&gt;

&lt;p&gt;On Android 12 and above, Google introduced strict restrictions on background services. Apps can no longer just run freely in the background. There are limits on when a service can start, and if you don't handle it correctly, the system kills your service entirely - meaning you miss clipboard items.&lt;/p&gt;

&lt;p&gt;Getting this right took significant work. CopyDuo uses a &lt;strong&gt;foreground service&lt;/strong&gt; (the kind Android officially supports for long-running tasks) with a persistent notification. This keeps the service alive reliably without fighting the system - and without draining your battery.&lt;/p&gt;

&lt;h3&gt;
  
  
  On New Devices, Apps Can't Read Your Clipboard in the Background
&lt;/h3&gt;

&lt;p&gt;This one genuinely surprised me.&lt;/p&gt;

&lt;p&gt;Starting with Android 10, Google added a privacy restriction: apps can only read clipboard data when they are &lt;strong&gt;actively in use&lt;/strong&gt; - meaning they're the foreground app the user is currently interacting with. A background service can't silently read your clipboard anymore.&lt;/p&gt;

&lt;p&gt;This is actually a good privacy decision. You don't want random apps reading everything you copy in the background. But it created a real problem for a clipboard manager.&lt;/p&gt;

&lt;p&gt;I had to find another way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The solution:&lt;/strong&gt; a button in the notification panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovwd8tepeaoccgojwmeh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovwd8tepeaoccgojwmeh.jpeg" alt="Notification Panel" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When CopyDuo is running, it shows a persistent notification. That notification has a &lt;strong&gt;"SAVE TEXT"&lt;/strong&gt; button. When you tap it, the app briefly comes to the foreground, reads your current clipboard content, saves it, and steps back. It's a one-tap action that takes less than a second.&lt;/p&gt;

&lt;p&gt;It's not the invisible magic I originally wanted, but it works reliably on every Android version - including the latest ones - without any workarounds that could break with future updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It Looks Like in Practice
&lt;/h2&gt;

&lt;p&gt;Your day-to-day usage looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You copy something → CopyDuo saves it automatically (on older devices) or you tap the notification button (on newer devices)&lt;/li&gt;
&lt;li&gt;You copy something else on top of it → no problem, both are saved&lt;/li&gt;
&lt;li&gt;Ten minutes later you need the first thing → open CopyDuo, tap it, done&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list shows your most recent 50 items. You can delete individual ones or clear everything at once.&lt;/p&gt;




&lt;h2&gt;
  
  
  Another Way to Save: the Text Selection Menu
&lt;/h2&gt;

&lt;p&gt;While working around the Android 10+ clipboard restriction, I found another clean solution that fits even more naturally into how people actually use their phones.&lt;/p&gt;

&lt;p&gt;When you long-press any text in any app — a browser, a PDF reader, a messaging app — Android shows a floating toolbar with options like Copy, Cut, and Share. CopyDuo adds its own button to that menu: &lt;strong&gt;"Save to CopyDuo"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6bq16hlnua5vm5u284h.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6bq16hlnua5vm5u284h.webp" alt="Save to Copyduo" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select any text → tap Save to CopyDuo → it's in your history. No need to copy first. No need to open the notification. No steps in between.&lt;/p&gt;

&lt;p&gt;This works everywhere Android shows the text selection menu. Reading an article and want to save a quote? Select it, tap Save to CopyDuo. Found a useful command in a tutorial? Same flow.&lt;/p&gt;

&lt;p&gt;Between the notification button and the text selection action, CopyDuo covers every scenario — whether you're copy-pasting quickly or deliberately saving something you just read.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Kept It Offline
&lt;/h2&gt;

&lt;p&gt;A lot of productivity apps want your data in the cloud. Sync across devices, access from anywhere - it sounds convenient.&lt;/p&gt;

&lt;p&gt;But your clipboard is where passwords live. Phone numbers. Bank account details. Private messages. One-time codes. The idea of that data leaving your device and sitting on someone's server made me uncomfortable - and I figured it would make you uncomfortable too.&lt;/p&gt;

&lt;p&gt;CopyDuo has &lt;strong&gt;no internet permission&lt;/strong&gt;. It physically cannot send your data anywhere. Everything is stored locally using a lightweight on-device database, and it never leaves your phone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Download CopyDuo
&lt;/h2&gt;

&lt;p&gt;It's free on the Google Play Store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.anoop.myprojects.copyduo" rel="noopener noreferrer"&gt;&lt;strong&gt;Get CopyDuo on Google Play →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Works on Android 8.0 and above. No account required. No subscription.&lt;/p&gt;




&lt;p&gt;If you've ever lost something you copied, give it a try. It solves exactly one problem - but it solves it well.&lt;/p&gt;

</description>
      <category>android</category>
      <category>productivity</category>
      <category>appdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Free, Offline Invoice App with Flutter - No Cloud, No Subscription, No BS</title>
      <dc:creator>anoop p</dc:creator>
      <pubDate>Thu, 12 Mar 2026 15:48:17 +0000</pubDate>
      <link>https://dev.to/anoop_p_22f715057ac8b3901/i-built-a-free-offline-invoice-app-with-flutter-no-cloud-no-subscription-no-bs-16dl</link>
      <guid>https://dev.to/anoop_p_22f715057ac8b3901/i-built-a-free-offline-invoice-app-with-flutter-no-cloud-no-subscription-no-bs-16dl</guid>
      <description>&lt;p&gt;Every time I needed to invoice a client, I ran into the same wall: every decent invoice tool either locks your data in the cloud, wants a monthly subscription, or both. I just wanted something that &lt;strong&gt;works offline, keeps my data on my machine, and doesn't cost me anything&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I built it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/Anooppandikashala/invoiso" rel="noopener noreferrer"&gt;Invoiso&lt;/a&gt;&lt;/strong&gt; is a free, open-source desktop invoice app for Windows and Linux. No account. No internet. No recurring fee. Just a binary you run on your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Flutter for a Desktop App?
&lt;/h2&gt;

&lt;p&gt;Flutter is usually talked about in the context of mobile. But Flutter's desktop support has matured a lot - and it gave me a few things I really wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One codebase for Windows and Linux&lt;/strong&gt; - I didn't want to maintain separate projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A rich widget ecosystem&lt;/strong&gt; - building forms, data tables, and PDF previews is fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dart's type safety&lt;/strong&gt; - for a data-heavy app with models, migrations, and services, it helps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The build output is a native binary - no Electron, no Chromium, no 300 MB runtime. The Linux AppImage is lean and starts instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tech&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Flutter 3.x (Dart)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;SQLite via &lt;code&gt;sqflite&lt;/code&gt; + &lt;code&gt;sqflite_common_ffi&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State Management&lt;/td&gt;
&lt;td&gt;Riverpod&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PDF Generation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf&lt;/code&gt; + &lt;code&gt;printing&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QR Codes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qr&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSV Export&lt;/td&gt;
&lt;td&gt;&lt;code&gt;csv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Window Management&lt;/td&gt;
&lt;td&gt;&lt;code&gt;window_manager&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Picker&lt;/td&gt;
&lt;td&gt;&lt;code&gt;file_picker&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SQLite with &lt;code&gt;sqflite_common_ffi&lt;/code&gt; is the key piece for desktop. The mobile &lt;code&gt;sqflite&lt;/code&gt; package doesn't work on Linux/Windows - &lt;code&gt;sqflite_common_ffi&lt;/code&gt; wraps the native SQLite library and exposes the same API, so the transition is seamless. All data lives in a single &lt;code&gt;.db&lt;/code&gt; file the user controls.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/
├── main.dart
├── common.dart          # Shared enums and data classes
├── constants.dart       # UI constants
├── database/            # SQLite helpers and CRUD services
├── models/              # Invoice, Customer, Product, ...
├── providers/           # Riverpod state providers
├── screens/             # All UI screens
├── services/            # PDF generation, CSV/PDF export
├── backup/              # Backup and restore logic
└── utils/               # Logger, formatters, error handler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database layer follows a service pattern - each entity (invoices, customers, products) has its own service class wrapping raw SQL. Migrations are handled manually in &lt;code&gt;database_helper.dart&lt;/code&gt; with a version counter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Interesting Technical Bits
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. PDF Generation with Three Templates
&lt;/h3&gt;

&lt;p&gt;PDF output is generated using the &lt;code&gt;pdf&lt;/code&gt; package (not a web renderer - actual vector PDF). I built three templates: &lt;strong&gt;Classic&lt;/strong&gt;, &lt;strong&gt;Modern&lt;/strong&gt;, and &lt;strong&gt;Minimal&lt;/strong&gt; - each with a distinct layout and color scheme.&lt;/p&gt;

&lt;p&gt;The tricky part was making the layout adaptive to variable-length item lists, long product descriptions, and optional sections (GST, UPI QR, logo). The &lt;code&gt;pdf&lt;/code&gt; package has its own layout model (similar to Flutter widgets but without hot reload - so a lot of trial and error).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. UPI Payment QR Code on Invoices
&lt;/h3&gt;

&lt;p&gt;For Indian users, I added UPI QR code embedding. When a UPI ID is configured in settings, the PDF generation encodes a &lt;code&gt;upi://pay?pa={upi_id}&amp;amp;am={total}&lt;/code&gt; URI into a QR code using the &lt;code&gt;qr&lt;/code&gt; package and renders it directly in the PDF footer. Clients can scan it with GPay, PhonePe, or Paytm to pay instantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Multi-Currency with Per-Invoice Snapshots
&lt;/h3&gt;

&lt;p&gt;Currency is selected globally in settings, but each invoice &lt;strong&gt;stores its own &lt;code&gt;currency_code&lt;/code&gt; and &lt;code&gt;currency_symbol&lt;/code&gt; at creation time&lt;/strong&gt;. This means if you change your default currency later, old invoices still display correctly. A simple but important detail - got it wrong the first time and had to add a DB migration.&lt;/p&gt;

&lt;p&gt;Speaking of migrations: I maintain a &lt;code&gt;DB_VERSION&lt;/code&gt; constant and a chain of &lt;code&gt;_upgradeDbV{n}&lt;/code&gt; functions. Each upgrade is additive (new columns with defaults, new tables) - no destructive changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Backup and Restore
&lt;/h3&gt;

&lt;p&gt;The backup feature is a plain file copy of the SQLite &lt;code&gt;.db&lt;/code&gt; file to a user-chosen directory. Restore reverses it. Simple, robust, and the user owns the backup file - they can put it on a USB drive, copy it to another machine, or commit it to their own repo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features at a Glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PDF invoices&lt;/strong&gt; - one-click generation in Classic, Modern, or Minimal templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invoices and Quotations&lt;/strong&gt; - with color-coded tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invoice cloning&lt;/strong&gt; - duplicate any document with one click&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk actions&lt;/strong&gt; - multi-select to export CSV, generate PDFs, or delete&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UPI QR code&lt;/strong&gt; - embedded scannable payment QR in every PDF&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GST ready&lt;/strong&gt; - GSTIN fields, HSN codes, per-item or global tax rate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-currency&lt;/strong&gt; - INR, USD, EUR, GBP, JPY, AED, SGD, AUD, CAD, JMD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer and product management&lt;/strong&gt; - full CRUD with search and pagination&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft delete / Trash&lt;/strong&gt; - recoverable deleted invoices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSV export&lt;/strong&gt; - for spreadsheets or accounting software&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup and restore&lt;/strong&gt; - one-click, local file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; - login with brute-force protection and session timeout&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% offline&lt;/strong&gt; - zero network calls, ever&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.exe&lt;/code&gt; installer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.AppImage&lt;/code&gt; (portable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.deb&lt;/code&gt; package&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Grab the latest from the &lt;strong&gt;&lt;a href="https://invoiso.co.in/download.html" rel="noopener noreferrer"&gt;Download page&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build from Source
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/Anooppandikashala/invoiso.git
&lt;span class="nb"&gt;cd &lt;/span&gt;invoiso
flutter pub get

&lt;span class="c"&gt;# Run in debug mode&lt;/span&gt;
flutter run &lt;span class="nt"&gt;-d&lt;/span&gt; linux    &lt;span class="c"&gt;# or -d windows&lt;/span&gt;

&lt;span class="c"&gt;# Release build&lt;/span&gt;
flutter build linux &lt;span class="nt"&gt;--release&lt;/span&gt;
flutter build windows &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prerequisites: Flutter SDK &amp;gt;= 3.3.3. On Linux you'll also need &lt;code&gt;clang&lt;/code&gt;, &lt;code&gt;cmake&lt;/code&gt;, &lt;code&gt;ninja-build&lt;/code&gt;, and &lt;code&gt;libgtk-3-dev&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;There's a solid list of planned features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Invoice status tracking&lt;/strong&gt; (Paid / Unpaid / Overdue / Draft) - the biggest gap right now&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Due dates and payment terms&lt;/strong&gt; (Net 7, Net 30, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment recording&lt;/strong&gt; with partial payment support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recurring invoices&lt;/strong&gt; for retainers and subscriptions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revenue reports&lt;/strong&gt; with date range filters&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dark mode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global search&lt;/strong&gt; across invoices, customers, and products&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GST report export&lt;/strong&gt; in GSTR-1 compatible format (for Indian users)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these interests you, contributions are welcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fork the repo&lt;/li&gt;
&lt;li&gt;Create a branch: &lt;code&gt;git checkout -b feature/your-feature&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open a pull request&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Bug reports and feature requests go in &lt;a href="https://github.com/Anooppandikashala/invoiso/issues" rel="noopener noreferrer"&gt;GitHub Issues&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;The whole thing is MIT licensed. If it saves you time or money, great - that's the point. If you want to help make it better, even better.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub: &lt;a href="https://github.com/Anooppandikashala/invoiso" rel="noopener noreferrer"&gt;github.com/Anooppandikashala/invoiso&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Website: &lt;a href="https://invoiso.co.in/" rel="noopener noreferrer"&gt;invoiso.co.in/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>invoise</category>
    </item>
  </channel>
</rss>
