Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copilot Instructions for BeInX

## Build, Test, and Lint Commands

### .NET (Blazor PWA)
- **Build:**
- `dotnet build` (run in `src` directory)
- **Test:**
- `dotnet test` (run in `src` directory)
- To run a single test, use: `dotnet test --filter FullyQualifiedName~<TestName>`
- **Restore:**
- `dotnet restore` (run in `src` directory)

### PDF Generation (TypeScript)
- **Setup:**
- Navigate to `src/BlazorInvoice.Pdf/Typescript`
- `npm install`
- **Build:**
- `npm run build` (uses webpack)
- **Test:**
- `npm test` (runs Vitest)
- To run a single test: `npx vitest run __tests__/pdf-generator.test.ts -t <test name>`
- **Lint:**
- If ESLint is configured: `npx eslint .`

## High-Level Architecture
- **Blazor WebAssembly PWA**: Main app in `src/beinx.pwa` (entry: `Program.cs`).
- **PDF Generation**: Handled by TypeScript in `src/BlazorInvoice.Pdf/Typescript`, built with webpack.
- **Localization**: Centralized in `src/beinx.locbuilder/Resources/InvoiceLoc.csv`. Run the `beinx.locbuilder` project to regenerate `.resx` files after updates.
- **Data Storage**: Uses IndexedDB in browser for offline support.
- **Multi-language**: English, German, Spanish, French supported.
- **Project References**: `beinx.pwa` references `beinx.db`, `beinx.web`, `beinx.shared`, and `BlazorInvoice.Pdf`.

## Key Conventions
- **Localization**: All translation keys and values are managed in a single CSV. Update this file and regenerate resources as needed.
- **PDF/TypeScript**: All PDF logic and tests are in `src/BlazorInvoice.Pdf/Typescript`. Use Vitest for testing.
- **.NET Version**: Project targets .NET 10.0 or higher.
- **PWA**: App is installable and works offline after first load.
- **Legal**: See `DISCLAIMER.md` and `LICENSE.md` for usage terms.

---

This file summarizes build/test commands, architecture, and conventions for Copilot and future contributors. Would you like to adjust anything or add coverage for other areas?
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ BeInX does not collect or transmit any personal data. See our full [privacy poli

# Change Log

<details open="open"><summary>v0.5.3</summary>
<details open="open"><summary>v0.5.4</summary>

>- Add c/o address line

</details>

<details><summary>v0.5.3</summary>

>- Update ZUGFeRD-csharp v18.0.0-beta2
>- Using basic ZUGFeRD-csharp format (ZUGFeRDVersion.Version23, Profile.Basic, ZUGFeRDFormats.CII)
Expand Down
2 changes: 1 addition & 1 deletion src/BlazorInvoice.Pdf/BlazorInvoice.Pdf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.*" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/BlazorInvoice.Pdf/Typescript/dtos/party-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface PartyDto {
logoReferenceId?: string,
name: string;
streetName?: string;
additionalStreetName?: string;
city: string;
postCode: string;
countryCode: string;
Expand Down
1,195 changes: 600 additions & 595 deletions src/BlazorInvoice.Pdf/Typescript/package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/BlazorInvoice.Pdf/Typescript/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blazor-invoice-pdf",
"version": "1.1.0",
"version": "1.2.0",
"description": "blazor invoice pdf generator",
"main": "index.js",
"scripts": {
Expand All @@ -12,17 +12,17 @@
"dependencies": {
"@pdf-lib/fontkit": "^1.1.1",
"pdf-lib": "^1.17.1",
"ts-loader": "^9.5.1",
"ts-loader": "^9.5.7",
"uuid": "^11.1.0"
},
"devDependencies": {
"@types/mocha": "^10.0.10",
"@types/node": "^22.10.5",
"@types/node": "^22.19.17",
"@vitest/ui": "^1.6.0",
"eslint": "^9.17.0",
"eslint": "^9.39.4",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.6.0",
"webpack": "^5.97.1",
"webpack": "^5.106.0",
"webpack-cli": "^6.0.1"
}
}
20 changes: 13 additions & 7 deletions src/BlazorInvoice.Pdf/Typescript/pdf-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,20 @@ export class PdfGenerator {
private drawBuyer(page: PDFPage, buyer: PartyDto): void {
let { x, y } = this.calculateStartPosition(page, 0, this.marginY * 2 - 30);

this.drawText(page, buyer.registrationName, x, y, 14);
this.drawText(page, buyer.streetName, x, y - 20, 14);
this.drawText(page, `${buyer.postCode} ${buyer.city}`, x, y - 36, 14);
this.drawText(page, buyer.registrationName, x, y, 16, this.fonts.bold);
this.drawText(page, buyer.streetName, x, y - 22, 14);
if (buyer.additionalStreetName) {
this.drawText(page, buyer.additionalStreetName, x, y - 36, 14);
this.drawText(page, `${buyer.postCode} ${buyer.city}`, x, y - 54, 16);
} else {
this.drawText(page, `${buyer.postCode} ${buyer.city}`, x, y - 40, 16);
}
}

private drawNote(page: PDFPage, invoice: InvoiceDto): number {
let { x, y } = this.calculateStartPosition(page, 0, this.marginY * 3 - 20);
let { x, y } = this.calculateStartPosition(page, 0, this.marginY * 3 - 15);

this.drawText(page, this.t("invoice"), x, y, 14, this.fonts.bold);
this.drawText(page, this.t("invoice"), x, y, 16, this.fonts.bold);
y -= 20;

if (invoice.note) {
Expand Down Expand Up @@ -658,7 +663,7 @@ export class PdfGenerator {
}

function generateObjectUrl(pdfBytes: Uint8Array): string {
const blob = new Blob([pdfBytes], { type: "application/pdf" });
const blob = new Blob([pdfBytes as unknown as BlobPart], { type: "application/pdf" });
return URL.createObjectURL(blob);
}

Expand Down Expand Up @@ -782,8 +787,9 @@ const sampleBuyer = (): PartyDto => {
postCode: "12345",
countryCode: "DE",
streetName: "Test Street 21",
additionalStreetName: "c/o test",
telefone: "",
registrationName: "",
registrationName: "Test Buyer",
taxId: "",
companyId: "",
};
Expand Down
Binary file modified src/BlazorInvoice.Pdf/Typescript/testinvoiceA3.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion src/BlazorInvoice.Pdf/wwwroot/dist/pdf-generator.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/beinx.db/Client/dtos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface IPartyBaseDto {
logoReferenceId?: string;
name: string;
streetName?: string;
additionalStreetName?: string;
city: string;
postCode: string;
countryCode: string;
Expand Down
2 changes: 1 addition & 1 deletion src/beinx.db/Client/tests/invoice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('invoices CRUD', () => {
const invoiceInfo = await getTestInvoiceInfo();
const id = await invoiceRepository.createInvoice(invoiceInfo, false);

await invoiceRepository.markAsPaid(id);
await invoiceRepository.setPaid(id, true);
const updated = await invoiceRepository.getById(id);
expect(updated?.isPaid).toBe(true);
});
Expand Down
1 change: 1 addition & 0 deletions src/beinx.db/Client/tests/party.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const getTestParty = (): IPartyBaseDto => ({
logoReferenceId: undefined,
name: 'Test Company Ltd.',
streetName: 'Test Street 123',
additionalStreetName: "c/o test",
city: 'Test City',
postCode: '12345',
countryCode: 'DE',
Expand Down
4 changes: 2 additions & 2 deletions src/beinx.db/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public static IServiceCollection AddBeinxDbServices(this IServiceCollection serv

// Buyer repository and draft
services.AddScoped<IBuyerRepository, BuyerRepository>();
services.AddScoped<IDraftRepository<BuyerAnnotationDto>>(sp =>
(IDraftRepository<BuyerAnnotationDto>)sp.GetRequiredService<IBuyerRepository>());
services.AddScoped<IDraftRepository<BlazorBuyerAnnotationDto>>(sp =>
(IDraftRepository<BlazorBuyerAnnotationDto>)sp.GetRequiredService<IBuyerRepository>());

services.AddScoped<IInvoiceRepository, InvoiceRepository>();
services.AddScoped<IDraftRepository<InvoiceDtoInfo>>(sp =>
Expand Down
2 changes: 1 addition & 1 deletion src/beinx.db/Services/InvoiceService.Import.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private async Task<int> GetSellerId(SellerAnnotationDto seller)
return await sellerRepository.CreateAsync(seller);
}

private async Task<int> GetBuyerId(BuyerAnnotationDto buyer)
private async Task<int> GetBuyerId(BlazorBuyerAnnotationDto buyer)
{
var buyers = await buyerRepository.GetAllAsync();

Expand Down
4 changes: 2 additions & 2 deletions src/beinx.db/Services/PartyRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public Task<int> CreateAsync(TDto dto)
=> _interop.CallAsync<int>("partyRepository.createParty", dto, _isSeller);

// Update an existing party
public async Task UpdateAsync(int id, IPartyBaseDto dto)
public async Task UpdateAsync(int id, TDto dto)
=> await _interop.CallVoidAsync("partyRepository.updateParty", id, dto, _isSeller);

// Delete a party
Expand Down Expand Up @@ -70,7 +70,7 @@ public SellerRepository(IIndexedDbInterop interop)
}
}

public class BuyerRepository : BasePartyRepository<BuyerAnnotationDto>, IBuyerRepository
public class BuyerRepository : BasePartyRepository<BlazorBuyerAnnotationDto>, IBuyerRepository
{
public BuyerRepository(IIndexedDbInterop interop)
: base(interop, isSeller: false)
Expand Down
4 changes: 3 additions & 1 deletion src/beinx.db/Services/ZugferdMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public static string MapToZugferd(BlazorInvoiceDto invoice)
GetEnum<CountryCodes>(invoice.BuyerParty.CountryCode),
id: string.Empty
);
desc.Buyer.AddressLine3 = invoice.BuyerParty.AdditionalStreetName;
desc.AddBuyerTaxRegistration(invoice.BuyerParty.TaxId, TaxRegistrationSchemeID.VA);
desc.SetBuyerElectronicAddress(invoice.BuyerParty.Email, ElectronicAddressSchemeIdentifiers.GermanyVatNumber);
desc.SetBuyerContact(
Expand Down Expand Up @@ -156,10 +157,11 @@ public static BlazorInvoiceDto MapFromZugferd(string xmlText)
InvoiceTypeCode = GetEnumAttributeValue(desc.Type),
Note = desc.Notes.FirstOrDefault()?.Content,
PayableAmount = (double)(desc.DuePayableAmount ?? 0),
BuyerParty = new BuyerAnnotationDto
BuyerParty = new BlazorBuyerAnnotationDto
{
Name = desc.Buyer?.Name ?? string.Empty,
StreetName = desc.Buyer?.Street,
AdditionalStreetName = desc.Buyer?.AddressLine3,
PostCode = desc.Buyer?.Postcode ?? string.Empty,
City = desc.Buyer?.City ?? string.Empty,
CountryCode = desc.Buyer?.Country.ToString() ?? string.Empty,
Expand Down
2 changes: 1 addition & 1 deletion src/beinx.db/beinx.db.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.0.*" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading