mirror of
https://github.com/frappe/books.git
synced 2024-11-08 23:00:56 +00:00
Merge branch 'master' into fix/profit-loss-report-filter-fields
This commit is contained in:
commit
23e633318c
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
- name: Setup Books
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn
|
||||
yarn upgrade frappejs
|
||||
yarn link frappejs
|
||||
|
||||
- name: Install RPM
|
||||
|
33
.github/workflows/publish.yml
vendored
33
.github/workflows/publish.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
- name: Setup Books
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn
|
||||
yarn upgrade frappejs
|
||||
yarn link frappejs
|
||||
|
||||
- name: Run build
|
||||
@ -50,6 +50,15 @@ jobs:
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn electron:build --mac --publish always
|
||||
|
||||
- name: Tar files
|
||||
run: tar -cvf dist-macOS.tar $GITHUB_WORKSPACE/main/dist_electron
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist-macOS
|
||||
path: dist-macOS.tar
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
@ -79,7 +88,7 @@ jobs:
|
||||
- name: Setup Books
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn
|
||||
yarn upgrade frappejs
|
||||
yarn link frappejs
|
||||
|
||||
- name: Run build
|
||||
@ -89,6 +98,15 @@ jobs:
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn electron:build --linux --publish always
|
||||
|
||||
- name: Tar files
|
||||
run: tar -cvf dist-linux.tar $GITHUB_WORKSPACE/main/dist_electron
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist-linux
|
||||
path: dist-linux.tar
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-2022
|
||||
defaults:
|
||||
@ -121,7 +139,7 @@ jobs:
|
||||
- name: Setup Books
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn
|
||||
yarn upgrade frappejs
|
||||
yarn link frappejs
|
||||
|
||||
- name: Run build
|
||||
@ -132,3 +150,12 @@ jobs:
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE/main
|
||||
yarn electron:build --win --publish always
|
||||
|
||||
- name: Tar files
|
||||
run: tar -cvf dist-windows.tar $GITHUB_WORKSPACE/main/dist_electron
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist-windows
|
||||
path: dist-windows.tar
|
@ -2,7 +2,7 @@ import { showMessageDialog } from '@/utils';
|
||||
import frappe from 'frappejs';
|
||||
import { _ } from 'frappejs/utils';
|
||||
import { DateTime } from 'luxon';
|
||||
import { saveExportData } from '../reports/commonExporter';
|
||||
import { saveExportData, exportCsv } from '../reports/commonExporter';
|
||||
import { getSavePath } from '../src/utils';
|
||||
|
||||
// prettier-ignore
|
||||
@ -252,3 +252,85 @@ async function generateB2csData(invoices) {
|
||||
|
||||
return b2cs;
|
||||
}
|
||||
|
||||
export async function generateGstr2Csv(getReportData) {
|
||||
const { gstin } = frappe.AccountingSettings;
|
||||
if (!gstin) {
|
||||
showMessageDialog({
|
||||
message: _('Export Failed'),
|
||||
description: _('Please set GSTIN in General Settings.'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
rows,
|
||||
columns,
|
||||
filters: { transferType, toDate },
|
||||
} = getReportData();
|
||||
|
||||
const { filePath, canceled } = await getSavePath('gstr-2', 'csv');
|
||||
if (canceled || !filePath) return;
|
||||
|
||||
let gstData;
|
||||
if (transferType === 'B2B') {
|
||||
gstData = await generateB2bCsvGstr2(rows, columns);
|
||||
}
|
||||
|
||||
await exportCsv(gstData.rows, gstData.columns, filePath);
|
||||
}
|
||||
|
||||
async function generateB2bCsvGstr2(rows, columns) {
|
||||
|
||||
const csvColumns = [
|
||||
{
|
||||
label: 'GSTIN of Supplier',
|
||||
fieldname: 'gstin',
|
||||
},
|
||||
{
|
||||
label: 'Invoice Number',
|
||||
fieldname: 'invNo',
|
||||
},
|
||||
{
|
||||
label: 'Invoice Date',
|
||||
fieldname: 'invDate',
|
||||
},
|
||||
{
|
||||
label: 'Invoice Value',
|
||||
fieldname: 'invAmt',
|
||||
},
|
||||
{
|
||||
label: 'Place of supply',
|
||||
fieldname: 'place',
|
||||
},
|
||||
{
|
||||
label: 'Reverse Charge',
|
||||
fieldname: 'reverseCharge',
|
||||
},
|
||||
{
|
||||
label: 'Rate',
|
||||
fieldname: 'rate',
|
||||
},
|
||||
{
|
||||
label: 'Taxable Value',
|
||||
fieldname: 'taxVal',
|
||||
},
|
||||
{
|
||||
label: 'Intergrated Tax Paid',
|
||||
fieldname: 'igstAmt',
|
||||
},
|
||||
{
|
||||
label: 'Central Tax Paid',
|
||||
fieldname: 'cgstAmt',
|
||||
},
|
||||
{
|
||||
label: 'State/UT Tax Paid',
|
||||
fieldname: 'sgstAmt',
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
columns: csvColumns,
|
||||
rows: rows,
|
||||
}
|
||||
}
|
@ -50,6 +50,12 @@ export default {
|
||||
label: 'State',
|
||||
placeholder: 'State',
|
||||
fieldtype: 'AutoComplete',
|
||||
emptyMessage: (doc) => {
|
||||
if (doc.country) {
|
||||
return 'Enter State';
|
||||
}
|
||||
return 'Enter Country to load States';
|
||||
},
|
||||
getList: getStates,
|
||||
},
|
||||
{
|
||||
|
@ -1,27 +1,11 @@
|
||||
import { DateTime } from 'luxon';
|
||||
import { generateGstr1Json, stateCodeMap } from '../../accounting/gst';
|
||||
import { stateCodeMap } from '../../accounting/gst';
|
||||
import { titleCase } from '../../src/utils';
|
||||
|
||||
const transferTypeMap = {
|
||||
B2B: 'B2B',
|
||||
B2CL: 'B2C-Large',
|
||||
B2CS: 'B2C-Small',
|
||||
NR: 'Nil Rated, Exempted and Non GST supplies',
|
||||
};
|
||||
const stateList = Object.keys(stateCodeMap).map(titleCase).sort();
|
||||
|
||||
export default {
|
||||
filterFields: [
|
||||
{
|
||||
fieldtype: 'Select',
|
||||
label: 'Transfer Type',
|
||||
placeholder: 'Transfer Type',
|
||||
fieldname: 'transferType',
|
||||
options: Object.keys(transferTypeMap),
|
||||
map: transferTypeMap,
|
||||
default: 'B2B',
|
||||
size: 'small',
|
||||
},
|
||||
{
|
||||
fieldtype: 'AutoComplete',
|
||||
label: 'Place',
|
||||
@ -47,17 +31,6 @@ export default {
|
||||
default: () => DateTime.local().toISODate(),
|
||||
},
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
group: 'Export',
|
||||
label: 'JSON',
|
||||
type: 'primary',
|
||||
action: async (report, filters) => {
|
||||
generateGstr1Json(report, filters);
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
getColumns({ filters }) {
|
||||
const columns = [
|
||||
{
|
||||
|
@ -1,10 +1,40 @@
|
||||
const title = 'GSTR 1';
|
||||
import baseConfig from './BaseViewConfig';
|
||||
import { generateGstr1Json } from '../../accounting/gst';
|
||||
|
||||
const transferTypeMap = {
|
||||
B2B: 'B2B',
|
||||
B2CL: 'B2C-Large',
|
||||
B2CS: 'B2C-Small',
|
||||
NR: 'Nil Rated, Exempted and Non GST supplies',
|
||||
};
|
||||
|
||||
const transferType = {
|
||||
fieldtype: 'Select',
|
||||
label: 'Transfer Type',
|
||||
placeholder: 'Transfer Type',
|
||||
fieldname: 'transferType',
|
||||
options: Object.keys(transferTypeMap),
|
||||
map: transferTypeMap,
|
||||
default: 'B2B',
|
||||
size: 'small',
|
||||
};
|
||||
|
||||
const actions = [
|
||||
{
|
||||
group: 'Export',
|
||||
label: 'JSON',
|
||||
type: 'primary',
|
||||
action: async (report, filters) => {
|
||||
generateGstr1Json(report, filters);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
title: title,
|
||||
method: 'gstr-1',
|
||||
filterFields: baseConfig.filterFields,
|
||||
actions: baseConfig.actions,
|
||||
filterFields: [ transferType, ...baseConfig.filterFields],
|
||||
actions: actions,
|
||||
getColumns: baseConfig.getColumns,
|
||||
};
|
||||
|
@ -16,9 +16,6 @@ class GSTR2 extends BaseGSTR {
|
||||
// prettier-ignore
|
||||
const conditions = {
|
||||
'B2B': row => row.gstin,
|
||||
'B2CL': row => !row.gstin && !row.inState && row.invAmt >= 250000,
|
||||
'B2CS': row =>
|
||||
!row.gstin && (row.inState || (row.inState && row.invAmt < 250000))
|
||||
};
|
||||
|
||||
if (!params.transferType) return data;
|
||||
|
@ -1,10 +1,37 @@
|
||||
const title = 'GSTR 2';
|
||||
import baseConfig from './BaseViewConfig';
|
||||
import { generateGstr2Csv } from '../../accounting/gst';
|
||||
|
||||
const transferTypeMap = {
|
||||
B2B: 'B2B',
|
||||
};
|
||||
|
||||
const transferType = {
|
||||
fieldtype: 'Select',
|
||||
label: 'Transfer Type',
|
||||
placeholder: 'Transfer Type',
|
||||
fieldname: 'transferType',
|
||||
options: Object.keys(transferTypeMap),
|
||||
map: transferTypeMap,
|
||||
default: 'B2B',
|
||||
size: 'small',
|
||||
};
|
||||
|
||||
const actions = [
|
||||
{
|
||||
group: 'Export',
|
||||
label: 'CSV',
|
||||
type: 'primary',
|
||||
action: async (report, filters) => {
|
||||
generateGstr2Csv(report, filters);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
title: title,
|
||||
method: 'gstr-2',
|
||||
filterFields: baseConfig.filterFields,
|
||||
actions: baseConfig.actions,
|
||||
filterFields: [ transferType, ...baseConfig.filterFields],
|
||||
actions: actions,
|
||||
getColumns: baseConfig.getColumns,
|
||||
};
|
||||
|
@ -34,7 +34,7 @@ function csvFormat(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
async function exportCsv(rows, columns, filePath) {
|
||||
export async function exportCsv(rows, columns, filePath) {
|
||||
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
||||
const labels = columns.map(({ label }) => csvFormat(label));
|
||||
const csvRows = [
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dropdown :items="suggestions" :is-loading="isLoading">
|
||||
<Dropdown :items="suggestions" :is-loading="isLoading" :df="df" :doc="doc">
|
||||
<template
|
||||
v-slot="{
|
||||
toggleDropdown,
|
||||
|
@ -35,7 +35,7 @@
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 14 14"
|
||||
fill="none"
|
||||
:fill="offColor"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect
|
||||
@ -44,7 +44,7 @@
|
||||
width="13"
|
||||
height="13"
|
||||
rx="3.5"
|
||||
:stroke="color"
|
||||
:stroke="offBorderColor"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
@ -71,7 +71,11 @@ export default {
|
||||
name: 'Check',
|
||||
extends: Base,
|
||||
data() {
|
||||
return { color: '#A1ABB4' };
|
||||
return {
|
||||
offBorderColor: 'rgba(17, 43, 66, 0.201322)',
|
||||
offColor: '#FFFFFF',
|
||||
color: '#A1ABB4'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
inputClasses() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<Popover @open="selectCurrentMonthYear">
|
||||
<template v-slot:target="{ togglePopover }">
|
||||
<template v-slot:target="{ togglePopover, handleBlur }">
|
||||
<input
|
||||
type="text"
|
||||
:class="inputClass"
|
||||
@ -8,6 +8,7 @@
|
||||
:placeholder="placeholder"
|
||||
readonly
|
||||
@focus="!readonly ? togglePopover() : null"
|
||||
@blur="handleBlur"
|
||||
/>
|
||||
</template>
|
||||
<template v-slot:content="{ togglePopover }">
|
||||
|
@ -21,8 +21,11 @@
|
||||
<div v-if="isLoading" class="p-2 text-gray-600 italic">
|
||||
{{ _('Loading...') }}
|
||||
</div>
|
||||
<div v-if="!isLoading && dropdownItems.length === 0" class="p-2 text-gray-600 italic">
|
||||
{{ _('Empty') }}
|
||||
<div
|
||||
v-if="!isLoading && dropdownItems.length === 0"
|
||||
class="p-2 text-gray-600 italic"
|
||||
>
|
||||
{{ getEmptyMessage() }}
|
||||
</div>
|
||||
<template v-else>
|
||||
<div v-for="d in dropdownItems" :key="d.label">
|
||||
@ -92,6 +95,12 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
df: {
|
||||
default: null,
|
||||
},
|
||||
doc: {
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Popover,
|
||||
@ -156,6 +165,15 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getEmptyMessage() {
|
||||
const { emptyMessage } = this.df ?? {};
|
||||
if (typeof emptyMessage === 'function') {
|
||||
return _(emptyMessage(this.doc));
|
||||
} else if (emptyMessage) {
|
||||
return _(emptyMessage);
|
||||
}
|
||||
return _('Empty');
|
||||
},
|
||||
selectItem(d) {
|
||||
if (d.action) {
|
||||
d.action();
|
||||
|
@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div ref="reference">
|
||||
<div class="h-full">
|
||||
<slot name="target" :togglePopover="togglePopover"></slot>
|
||||
<slot
|
||||
name="target"
|
||||
:togglePopover="togglePopover"
|
||||
:handleBlur="handleBlur"
|
||||
></slot>
|
||||
</div>
|
||||
<div
|
||||
ref="popover"
|
||||
@ -125,6 +129,9 @@ export default {
|
||||
this.isOpen = false;
|
||||
this.$emit('close');
|
||||
},
|
||||
handleBlur({ relatedTarget }) {
|
||||
relatedTarget && this.close();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -11,7 +11,6 @@
|
||||
items-center
|
||||
mb-3
|
||||
w-60
|
||||
bg-gray-100
|
||||
"
|
||||
style="transition: opacity 150ms ease-in"
|
||||
:style="{ opacity }"
|
||||
|
@ -283,6 +283,9 @@ export default {
|
||||
}
|
||||
|
||||
switch (key) {
|
||||
case 'Invoice':
|
||||
await this.updateChecks({ invoiceSetup: 1 });
|
||||
break;
|
||||
case 'General':
|
||||
await this.updateChecks({ companySetup: 1 });
|
||||
break;
|
||||
@ -323,11 +326,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
let printSettings = await frappe.getSingle('PrintSettings');
|
||||
if (printSettings.logo && printSettings.address) {
|
||||
toUpdate.invoiceSetup = 1;
|
||||
}
|
||||
|
||||
if (!frappe.GetStarted.itemCreated) {
|
||||
let { count } = (
|
||||
await frappe.db.knex('Item').count('name as count')
|
||||
|
@ -22,12 +22,12 @@
|
||||
class="w-40 ml-2 first:ml-0"
|
||||
:class="
|
||||
df.fieldtype === 'Check' &&
|
||||
'flex justify-between items-center bg-gray-100 px-2 overflow-scroll rounded'
|
||||
'flex justify-between items-center bg-gray-100 px-2 rounded'
|
||||
"
|
||||
v-for="df in report.filterFields"
|
||||
:key="df.fieldname"
|
||||
>
|
||||
<div v-if="df.fieldtype === 'Check'" class="text-sm">
|
||||
<div v-if="df.fieldtype === 'Check'" class="text-sm mr-2">
|
||||
{{ df.label }}
|
||||
</div>
|
||||
<FormControl
|
||||
|
@ -19,7 +19,9 @@ export default {
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
this.doc = await frappe.getSingle('AccountingSettings');
|
||||
this.doc = await frappe.getDoc('AccountingSettings', 'AccountingSettings', {
|
||||
skipDocumentCache: true
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
|
@ -99,6 +99,11 @@ const config = {
|
||||
label: _('GSTR1'),
|
||||
route: '/report/gstr-1',
|
||||
hidden: () => frappe.AccountingSettings.country !== 'India',
|
||||
},
|
||||
{
|
||||
label: _('GSTR2'),
|
||||
route: '/report/gstr-2',
|
||||
hidden: () => frappe.AccountingSettings.country !== 'India',
|
||||
}
|
||||
],
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user