tin-spa 20.3.6 → 20.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/tin-spa.mjs +110 -8
- package/fesm2022/tin-spa.mjs.map +1 -1
- package/index.d.ts +10 -0
- package/package.json +1 -1
package/fesm2022/tin-spa.mjs
CHANGED
|
@@ -1529,6 +1529,7 @@ class DataServiceLib {
|
|
|
1529
1529
|
this.capAccounts = new CapItem;
|
|
1530
1530
|
this.capAggregates = new CapItem; // Added: Capability for aggregates view
|
|
1531
1531
|
this.capAging = new CapItem; // Added: Capability for aging report
|
|
1532
|
+
this.capTaxRates = new CapItem; // Changed: Capability for tax rates management
|
|
1532
1533
|
this.capTransactionTypes = new CapItem;
|
|
1533
1534
|
this.capTransactions = new CapItem;
|
|
1534
1535
|
this.capAccountingInvoices = new CapItem;
|
|
@@ -2224,7 +2225,7 @@ class DataServiceLib {
|
|
|
2224
2225
|
this.capAccounting.name = "cap27";
|
|
2225
2226
|
this.capAccounting.display = "Accounting";
|
|
2226
2227
|
this.capAccounting.icon = "account_balance";
|
|
2227
|
-
this.capAccounting.capSubItems = [this.capAccounts, this.capTransactions, this.capAggregates, this.capTransactionTypes,];
|
|
2228
|
+
this.capAccounting.capSubItems = [this.capAccounts, this.capTransactions, this.capAggregates, this.capTransactionTypes, this.capTaxRates,]; // Changed: Added Tax Rates to Accounting submenu
|
|
2228
2229
|
this.capAccounts.name = "cap52"; // Changed: Fixed conflict with capBrands (was cap14)
|
|
2229
2230
|
this.capAccounts.display = "Accounts";
|
|
2230
2231
|
this.capAccounts.link = "home/admin/accounting-accounts";
|
|
@@ -2233,6 +2234,10 @@ class DataServiceLib {
|
|
|
2233
2234
|
this.capAggregates.display = "Aggregates";
|
|
2234
2235
|
this.capAggregates.link = "home/admin/accounting-aggregates";
|
|
2235
2236
|
this.capAggregates.icon = "bar_chart";
|
|
2237
|
+
this.capTaxRates.name = "cap60"; // Changed: Tax rates capability
|
|
2238
|
+
this.capTaxRates.display = "Tax Rates";
|
|
2239
|
+
this.capTaxRates.link = "home/admin/accounting-tax-rates";
|
|
2240
|
+
this.capTaxRates.icon = "percent";
|
|
2236
2241
|
this.capTransactionTypes.name = "cap28";
|
|
2237
2242
|
this.capTransactionTypes.display = "Transaction Types";
|
|
2238
2243
|
this.capTransactionTypes.link = "home/admin/accounting-transaction-types";
|
|
@@ -2823,6 +2828,8 @@ class AccountingService {
|
|
|
2823
2828
|
{ name: 'paymentTerms', type: 'select', alias: 'Payment Terms', required: true, defaultValue: 30, loadAction: { url: 'invoices/list/payment-terms' } },
|
|
2824
2829
|
{ name: 'dueDate', type: 'date', alias: 'Due Date', readonly: true, hideOnCreate: true },
|
|
2825
2830
|
{ name: 'status', type: 'select', hideOnCreate: true, readonly: true, loadAction: { url: 'invoices/list/statuses' } },
|
|
2831
|
+
{ name: 'subTotal', type: 'money', alias: 'Sub Total', readonly: true, hideOnCreate: true }, // Changed: Show SubTotal (before tax)
|
|
2832
|
+
{ name: 'taxTotal', type: 'money', alias: 'VAT', readonly: true, hideOnCreate: true }, // Changed: Show TaxTotal (VAT amount)
|
|
2826
2833
|
{ name: 'totalDisplay', type: 'label', alias: 'Total', format: 'text', readonly: true, hideOnCreate: true },
|
|
2827
2834
|
{ name: 'paidAmount', type: 'label', alias: 'Paid', readonly: true, hideOnCreate: true },
|
|
2828
2835
|
{ name: 'outstandingAmount', type: 'label', alias: 'Outstanding', readonly: true, hideOnCreate: true }
|
|
@@ -2856,11 +2863,20 @@ class AccountingService {
|
|
|
2856
2863
|
{ name: 'description', type: 'text', required: true, alias: 'Description', span: true }, // Changed: Description field (backend will populate for Product/Service)
|
|
2857
2864
|
{ name: 'quantity', type: 'number', required: true, defaultValue: 1 },
|
|
2858
2865
|
{ name: 'unitPrice', type: 'money', alias: 'Unit Price', required: true }, // Changed: Unit price field (backend will populate for Product/Service)
|
|
2859
|
-
{ name: 'poNumber', type: 'text', alias: 'PO Number',
|
|
2866
|
+
{ name: 'poNumber', type: 'text', alias: 'PO Number', }, // Added: PO Number for invoice bundling
|
|
2860
2867
|
],
|
|
2861
2868
|
loadAction: { url: 'invoiceitems/id/{invoiceItemID}' },
|
|
2862
2869
|
heroField: 'invoiceItemID',
|
|
2863
2870
|
};
|
|
2871
|
+
this.invoiceItemEditButton = { name: 'edit', dialog: true, action: { url: 'invoiceitems?action=edit', method: 'post' }, disabled: x => x.status != InvoiceStatus.Draft };
|
|
2872
|
+
// Invoice item details dialog config
|
|
2873
|
+
this.invoiceItemDetailsConfig = {
|
|
2874
|
+
formConfig: this.invoiceItemsFormConfig,
|
|
2875
|
+
heroField: 'invoiceItemID',
|
|
2876
|
+
buttons: [
|
|
2877
|
+
this.invoiceItemEditButton
|
|
2878
|
+
]
|
|
2879
|
+
};
|
|
2864
2880
|
// Added: Move item form configuration - select destination invoice
|
|
2865
2881
|
this.invoiceMoveItemFormConfig = {
|
|
2866
2882
|
title: 'Move Item',
|
|
@@ -2890,15 +2906,17 @@ class AccountingService {
|
|
|
2890
2906
|
causeFormRefresh: true,
|
|
2891
2907
|
columns: [
|
|
2892
2908
|
{ name: 'invoiceItemID', type: 'number', alias: 'ID', hiddenCondition: () => true },
|
|
2893
|
-
{ name: 'description', type: '
|
|
2909
|
+
{ name: 'description', type: 'chip', alias: 'Description', detailsConfig: this.invoiceItemDetailsConfig },
|
|
2894
2910
|
{ name: 'poNumber', type: 'text', alias: 'PO#' }, // Added: Purchase Order Number column
|
|
2895
2911
|
{ name: 'quantity', type: 'number', alias: 'Qty' },
|
|
2896
2912
|
{ name: 'unitPrice', type: 'money', alias: 'Unit Price' },
|
|
2897
|
-
{ name: 'amount', type: 'money', alias: 'Amount' }
|
|
2913
|
+
{ name: 'amount', type: 'money', alias: 'Amount' },
|
|
2914
|
+
{ name: 'taxAmount', type: 'money', alias: 'Tax' }, // Changed: Show per-item tax amount
|
|
2915
|
+
{ name: 'lineTotal', type: 'money', alias: 'Total' } // Changed: Computed line total (amount + tax)
|
|
2898
2916
|
],
|
|
2899
2917
|
buttons: [
|
|
2900
2918
|
{ name: 'create', display: 'Add Item', dialog: true, action: { url: 'invoiceitems?action=create', method: 'post' }, disabled: x => x.status != InvoiceStatus.Draft },
|
|
2901
|
-
|
|
2919
|
+
this.invoiceItemEditButton,
|
|
2902
2920
|
{ name: 'move', display: 'Move', dialog: true, icon: { name: 'swap_horiz' }, detailsConfig: this.invoiceMoveItemDetailsConfig, disabled: x => x.status != InvoiceStatus.Draft }, // Added: Move item button
|
|
2903
2921
|
{ name: 'delete', inDialog: true, icon: { name: 'delete', color: 'red' }, action: { url: 'invoiceitems?action=delete', method: 'post', successMessage: 'Deleted' }, confirm: { message: 'Delete this item?' }, disabled: x => x.status != InvoiceStatus.Draft },
|
|
2904
2922
|
],
|
|
@@ -2913,7 +2931,13 @@ class AccountingService {
|
|
|
2913
2931
|
this.invoiceDiscardButton = { name: 'discard', inDialog: true, display: 'Discard', icon: { name: 'close', color: 'red' },
|
|
2914
2932
|
action: { url: 'invoices?action=discard', method: 'post', successMessage: 'Discarded' },
|
|
2915
2933
|
confirm: { message: 'Invoice will be marked as cancelled?' },
|
|
2916
|
-
visible: x => x.status == InvoiceStatus.Draft
|
|
2934
|
+
visible: x => x.status == InvoiceStatus.Draft // Changed: Only allow on Draft (use Return for Submitted)
|
|
2935
|
+
};
|
|
2936
|
+
// Changed: Return button — reverts submitted invoice back to draft, reverses accounting transactions
|
|
2937
|
+
this.invoiceReturnButton = { name: 'return', inDialog: true, display: 'Return', icon: { name: 'undo', color: 'orange' },
|
|
2938
|
+
action: { url: 'invoices?action=return', method: 'post', successMessage: 'Returned to Draft' },
|
|
2939
|
+
confirm: { message: 'Return invoice to draft? This will reverse the receivable and VAT transactions.' },
|
|
2940
|
+
visible: x => x.status == InvoiceStatus.Submitted
|
|
2917
2941
|
};
|
|
2918
2942
|
this.invoiceSubmitButton = { name: 'submit', inDialog: true, display: 'Submit', icon: { name: 'send', },
|
|
2919
2943
|
action: { url: 'invoices?action=submit', method: 'post', successMessage: 'Submitted' },
|
|
@@ -2934,6 +2958,7 @@ class AccountingService {
|
|
|
2934
2958
|
buttons: [
|
|
2935
2959
|
this.invoiceSubmitButton,
|
|
2936
2960
|
this.invoiceRecordPaymentButton,
|
|
2961
|
+
this.invoiceReturnButton, // Changed: Return submitted invoice to draft
|
|
2937
2962
|
this.invoiceDiscardButton,
|
|
2938
2963
|
this.invoiceEditButton
|
|
2939
2964
|
]
|
|
@@ -2984,6 +3009,7 @@ class AccountingService {
|
|
|
2984
3009
|
// { name: 'view', dialog: true, detailsConfig: this.invoiceDetailsDialogConfig },
|
|
2985
3010
|
this.invoiceSubmitButton,
|
|
2986
3011
|
this.invoiceRecordPaymentButton,
|
|
3012
|
+
this.invoiceReturnButton, // Changed: Return submitted invoice to draft
|
|
2987
3013
|
// this.invoicePayButton,
|
|
2988
3014
|
this.invoiceDiscardButton,
|
|
2989
3015
|
// this.invoiceEditButton,
|
|
@@ -3098,6 +3124,47 @@ class AccountingService {
|
|
|
3098
3124
|
formConfig: this.outstandingInvoicesFormConfig,
|
|
3099
3125
|
tileConfig: this.outstandingInvoicesTileConfig
|
|
3100
3126
|
};
|
|
3127
|
+
//--------------------------Tax Rates-------------------------
|
|
3128
|
+
// Changed: Tax Rate form configuration for VAT management
|
|
3129
|
+
this.taxRateFormConfig = {
|
|
3130
|
+
title: 'Tax Rate',
|
|
3131
|
+
includeAudit: true,
|
|
3132
|
+
fields: [
|
|
3133
|
+
{ name: 'name', type: 'text', required: true, alias: 'Name' },
|
|
3134
|
+
{ name: 'rate', type: 'number', required: true, alias: 'Rate (%)' },
|
|
3135
|
+
{ name: 'isDefault', type: 'checkbox', alias: 'Default Rate' },
|
|
3136
|
+
{ name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true }
|
|
3137
|
+
],
|
|
3138
|
+
loadAction: { url: 'taxrates/id' },
|
|
3139
|
+
heroField: 'taxRateID'
|
|
3140
|
+
};
|
|
3141
|
+
this.taxRateCreateButton = { name: 'create', display: 'Create Tax Rate', dialog: true, action: { url: 'taxrates?action=create', method: 'post' } };
|
|
3142
|
+
this.taxRateEditButton = { name: 'edit', dialog: true, action: { url: 'taxrates?action=edit', method: 'post' } };
|
|
3143
|
+
this.taxRateDeleteButton = { name: 'delete', dialog: true, action: { url: 'taxrates?action=delete', method: 'post' } };
|
|
3144
|
+
this.taxRateDetailsConfig = {
|
|
3145
|
+
formConfig: this.taxRateFormConfig,
|
|
3146
|
+
heroField: 'taxRateID',
|
|
3147
|
+
buttons: [this.taxRateCreateButton, this.taxRateEditButton, this.taxRateDeleteButton]
|
|
3148
|
+
};
|
|
3149
|
+
this.taxRatesTableConfig = {
|
|
3150
|
+
showFilter: true,
|
|
3151
|
+
flatButtons: true,
|
|
3152
|
+
minColumns: ['name', 'rate', 'isActive'],
|
|
3153
|
+
columns: [
|
|
3154
|
+
{ name: 'name', type: 'text', alias: 'Name' },
|
|
3155
|
+
{ name: 'rate', type: 'number', alias: 'Rate (%)' },
|
|
3156
|
+
{ name: 'isDefault', type: 'checkbox', alias: 'Default' },
|
|
3157
|
+
{ name: 'isActive', type: 'checkbox', alias: 'Active' }
|
|
3158
|
+
],
|
|
3159
|
+
buttons: [
|
|
3160
|
+
this.taxRateCreateButton,
|
|
3161
|
+
{ name: 'view', dialog: true, detailsConfig: this.taxRateDetailsConfig },
|
|
3162
|
+
this.taxRateEditButton,
|
|
3163
|
+
this.taxRateDeleteButton
|
|
3164
|
+
],
|
|
3165
|
+
loadAction: { url: 'taxrates/all/x' },
|
|
3166
|
+
formConfig: this.taxRateFormConfig
|
|
3167
|
+
};
|
|
3101
3168
|
//--------------------------Transaction Types-------------------------
|
|
3102
3169
|
this.transactionTypeFormConfig = {
|
|
3103
3170
|
security: { allow: [this.dataService.capTransactionTypes] },
|
|
@@ -3807,6 +3874,8 @@ class InventoryService {
|
|
|
3807
3874
|
{ name: 'isBundle', type: 'checkbox', alias: 'Bundle Product', span: true, section: 'productInfo', infoMessage: 'Check if this is a bundle/combo product made up of other products' }, // Added: Bundle product flag
|
|
3808
3875
|
{ name: 'pricingInfo', type: 'section', alias: 'Pricing' },
|
|
3809
3876
|
{ name: 'sellingPrice', type: 'money', required: true, alias: 'Selling Price', section: 'pricingInfo', infoMessage: 'Default selling price per unit' },
|
|
3877
|
+
{ name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, section: 'pricingInfo', loadAction: { url: 'products/list/tax-rates' }, infoMessage: 'VAT rate applied to this product' }, // Changed: Tax rate selector
|
|
3878
|
+
{ name: 'isTaxInclusive', type: 'checkbox', alias: 'Price includes Tax', section: 'pricingInfo', infoMessage: 'If checked, the selling price already includes tax' }, // Changed: Tax-inclusive flag
|
|
3810
3879
|
{ name: 'inventoryInfo', type: 'section', alias: 'Inventory Settings', collapsedCondition: x => x.productID },
|
|
3811
3880
|
{ name: 'isSerialized', type: 'checkbox', alias: 'Serialized Product', span: true, section: 'inventoryInfo', infoMessage: 'Track individual items by serial number', hiddenCondition: x => x.isBundle }, // Changed: Hide for bundles
|
|
3812
3881
|
{ name: 'baseUnit', type: 'select', required: true, alias: 'Base Unit', section: 'inventoryInfo', loadAction: { url: 'products/list/base-unit' }, defaultFirstValue: true, infoMessage: 'Unit of measure for inventory tracking' }, // Changed: Added defaultFirstValue flag
|
|
@@ -3834,8 +3903,11 @@ class InventoryService {
|
|
|
3834
3903
|
{ name: 'brandName', type: 'text', alias: 'Brand' },
|
|
3835
3904
|
{ name: 'currentInventoryLevel', type: 'number', alias: 'Current Stock', icon: { name: 'warning', color: 'orange', condition: (x) => x.isLowInventory } }, // Changed: Removed separate columns, added low stock icon to current stock
|
|
3836
3905
|
{ name: 'minimumInventoryLevel', type: 'number', alias: 'Min Stock' },
|
|
3837
|
-
{ name: 'sellingPrice', type: 'money'
|
|
3838
|
-
|
|
3906
|
+
{ name: 'sellingPrice', type: 'money' },
|
|
3907
|
+
{ name: 'taxRateName', type: 'text', alias: 'Tax Rate' }, // Changed: Tax rate display with N/A fallback
|
|
3908
|
+
{ name: 'priceExclTax', type: 'text', alias: 'Price (Excl)' }, // Changed: Computed price excluding tax
|
|
3909
|
+
{ name: 'priceInclTax', type: 'text', alias: 'Price (Incl)' }, // Changed: Computed price including tax
|
|
3910
|
+
],
|
|
3839
3911
|
buttons: [
|
|
3840
3912
|
this.productCreateButton,
|
|
3841
3913
|
this.productViewButton,
|
|
@@ -3951,6 +4023,8 @@ class InventoryService {
|
|
|
3951
4023
|
{ name: 'isActive', type: 'checkbox', alias: 'Active', defaultValue: true },
|
|
3952
4024
|
{ name: 'description', type: 'text', alias: 'Description' },
|
|
3953
4025
|
{ name: 'unitPrice', type: 'money', required: true, alias: 'Unit Price' },
|
|
4026
|
+
{ name: 'taxRateID', type: 'select', alias: 'Tax Rate', nullable: true, loadAction: { url: 'serviceitems/list/tax-rates' }, infoMessage: 'VAT rate applied to this service' }, // Changed: Tax rate selector
|
|
4027
|
+
{ name: 'isTaxInclusive', type: 'checkbox', alias: 'Price includes Tax', infoMessage: 'If checked, the unit price already includes tax' }, // Changed: Tax-inclusive flag
|
|
3954
4028
|
],
|
|
3955
4029
|
loadAction: { url: 'serviceitems/id' },
|
|
3956
4030
|
heroField: 'serviceItemID'
|
|
@@ -3971,6 +4045,9 @@ class InventoryService {
|
|
|
3971
4045
|
{ name: 'name', type: 'text', alias: 'Service Name' },
|
|
3972
4046
|
{ name: 'description', type: 'text', alias: 'Description' },
|
|
3973
4047
|
{ name: 'unitPrice', type: 'money', alias: 'Unit Price' },
|
|
4048
|
+
{ name: 'taxRateName', type: 'text', alias: 'Tax Rate' }, // Changed: Tax rate display with N/A fallback
|
|
4049
|
+
{ name: 'priceExclTax', type: 'text', alias: 'Price (Excl)' }, // Changed: Computed price excluding tax
|
|
4050
|
+
{ name: 'priceInclTax', type: 'text', alias: 'Price (Incl)' }, // Changed: Computed price including tax
|
|
3974
4051
|
{ name: 'statusName', type: 'text', alias: 'Status' }
|
|
3975
4052
|
],
|
|
3976
4053
|
buttons: [
|
|
@@ -4778,6 +4855,8 @@ class InventoryService {
|
|
|
4778
4855
|
{ name: 'check_circle', color: '#4CAF50', condition: (x) => x.paymentStatus === 1, tip: 'Paid' } // Changed: Use status enum
|
|
4779
4856
|
]
|
|
4780
4857
|
},
|
|
4858
|
+
{ name: 'subTotal', type: 'money', alias: 'Sub Total' }, // Changed: Show subtotal before tax
|
|
4859
|
+
{ name: 'taxAmount', type: 'money', alias: 'Tax' }, // Changed: Show tax amount
|
|
4781
4860
|
{ name: 'totalAmount', type: 'money', alias: 'Total' }
|
|
4782
4861
|
],
|
|
4783
4862
|
buttons: [
|
|
@@ -16740,6 +16819,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImpo
|
|
|
16740
16819
|
}]
|
|
16741
16820
|
}] });
|
|
16742
16821
|
|
|
16822
|
+
// Tax Rates management page - CRUD for VAT tax rates
|
|
16823
|
+
class TaxRatesComponent {
|
|
16824
|
+
constructor() {
|
|
16825
|
+
this.accountingService = inject(AccountingService);
|
|
16826
|
+
this.pageConfig = {
|
|
16827
|
+
title: 'Tax Rates',
|
|
16828
|
+
tableConfig: this.accountingService.taxRatesTableConfig
|
|
16829
|
+
};
|
|
16830
|
+
}
|
|
16831
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TaxRatesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
16832
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.14", type: TaxRatesComponent, isStandalone: true, selector: "spa-tax-rates", ngImport: i0, template: '<spa-page [config]="pageConfig"></spa-page>', isInline: true, dependencies: [{ kind: "ngmodule", type: TinSpaModule }, { kind: "component", type: PageComponent, selector: "spa-page", inputs: ["config"], outputs: ["searchModeActivated", "searchModeDeactivated", "refreshClick", "actionClick", "actionResponse", "inputChange", "createClick", "searchClick", "dataLoad", "titleActionChange"] }] }); }
|
|
16833
|
+
}
|
|
16834
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: TaxRatesComponent, decorators: [{
|
|
16835
|
+
type: Component,
|
|
16836
|
+
args: [{
|
|
16837
|
+
selector: 'spa-tax-rates',
|
|
16838
|
+
standalone: true,
|
|
16839
|
+
imports: [TinSpaModule],
|
|
16840
|
+
template: '<spa-page [config]="pageConfig"></spa-page>'
|
|
16841
|
+
}]
|
|
16842
|
+
}] });
|
|
16843
|
+
|
|
16743
16844
|
class GptCachesComponent {
|
|
16744
16845
|
constructor() {
|
|
16745
16846
|
this.dataService = inject(DataServiceLib);
|
|
@@ -16796,6 +16897,7 @@ const routes$1 = [
|
|
|
16796
16897
|
{ path: "accounting-invoices", component: InvoicesComponent },
|
|
16797
16898
|
{ path: "accounting-aging", component: AgingComponent }, // Added: Aging route
|
|
16798
16899
|
{ path: "accounting-outstanding-invoices", component: OutstandingInvoicesComponent },
|
|
16900
|
+
{ path: "accounting-tax-rates", component: TaxRatesComponent }, // Changed: Tax rates management route
|
|
16799
16901
|
{ path: "loans-products", component: LoanProductsComponent },
|
|
16800
16902
|
{ path: "loans", component: LoansComponent },
|
|
16801
16903
|
{ path: "loans-payments", component: LoanPaymentsComponent },
|