Forráskód Böngészése

Some fixes to ALV-laskenta

svalavuo 13 órája
szülő
commit
6697c8061f

+ 105 - 39
backend/api/alv_laskenta.php

@@ -24,48 +24,67 @@ try {
     $period = $_GET['period'] ?? 'current';
     $month = $_GET['month'] ?? null;
     $year = $_GET['year'] ?? null;
+    $report_type = $_GET['report_type'] ?? 'standard'; // 'standard' or 'monthly_summary'
     
     // Determine date range based on period
     $dateConditions = getDateConditions($period, $month, $year);
     
-    // Fetch accounting entries for VAT calculation
-    $sql = "SELECT 
-                ae.*,
-                ac.category_name,
-                ac.category_type,
-                ac.vat_percentage as category_vat
-            FROM accounting_entries ae
-            LEFT JOIN accounting_categories ac ON ae.category = ac.category_code
-            WHERE ae.entry_date BETWEEN :start_date AND :end_date
-            ORDER BY ae.entry_date";
-    
-    $stmt = $conn->prepare($sql);
-    $stmt->bindParam(':start_date', $dateConditions['start_date']);
-    $stmt->bindParam(':end_date', $dateConditions['end_date']);
-    $stmt->execute();
-    
-    $entries = $stmt->fetchAll(PDO::FETCH_ASSOC);
-    
-    // Calculate VAT breakdown
-    $vatBreakdown = calculateVATBreakdown($entries);
-    
-    // Get previous period data for comparison
-    $previousDateConditions = getPreviousDateConditions($period, $month, $year);
-    $previousData = getPreviousPeriodVATData($conn, $previousDateConditions);
-    
-    // Combine current and previous data
-    $result = [
-        'period' => $period,
-        'date_range' => $dateConditions,
-        'vat_breakdown' => $vatBreakdown,
-        'previous_period' => $previousData,
-        'totals' => calculateVATTotals($vatBreakdown)
-    ];
-    
-    echo json_encode([
-        'success' => true,
-        'data' => $result
-    ]);
+    if ($report_type === 'monthly_summary') {
+        // Generate monthly summary report
+        error_log("Generating monthly summary for period: " . $period . " from " . $dateConditions['start_date'] . " to " . $dateConditions['end_date']);
+        $monthlyData = generateMonthlyVATSummary($conn, $dateConditions);
+        error_log("Monthly summary data: " . json_encode($monthlyData));
+        
+        echo json_encode([
+            'success' => true,
+            'data' => [
+                'report_type' => 'monthly_summary',
+                'period' => $period,
+                'date_range' => $dateConditions,
+                'monthly_summary' => $monthlyData
+            ]
+        ]);
+    } else {
+        // Standard VAT calculation
+        // Fetch accounting entries for VAT calculation
+        $sql = "SELECT 
+                    ae.*,
+                    ac.category_name,
+                    ac.category_type,
+                    ac.vat_percentage as category_vat
+                FROM accounting_entries ae
+                LEFT JOIN accounting_categories ac ON ae.category = ac.category_code
+                WHERE ae.entry_date BETWEEN :start_date AND :end_date
+                ORDER BY ae.entry_date";
+        
+        $stmt = $conn->prepare($sql);
+        $stmt->bindParam(':start_date', $dateConditions['start_date']);
+        $stmt->bindParam(':end_date', $dateConditions['end_date']);
+        $stmt->execute();
+        
+        $entries = $stmt->fetchAll(PDO::FETCH_ASSOC);
+        
+        // Calculate VAT breakdown
+        $vatBreakdown = calculateVATBreakdown($entries);
+        
+        // Get previous period data for comparison
+        $previousDateConditions = getPreviousDateConditions($period, $month, $year);
+        $previousData = getPreviousPeriodVATData($conn, $previousDateConditions);
+        
+        // Combine current and previous data
+        $result = [
+            'period' => $period,
+            'date_range' => $dateConditions,
+            'vat_breakdown' => $vatBreakdown,
+            'previous_period' => $previousData,
+            'totals' => calculateVATTotals($vatBreakdown)
+        ];
+        
+        echo json_encode([
+            'success' => true,
+            'data' => $result
+        ]);
+    }
     
 } catch (Exception $e) {
     http_response_code(500);
@@ -86,7 +105,7 @@ function getDateConditions($period, $month, $year) {
                 'end_date' => date('Y-m-t', strtotime("$currentYear-$currentMonth-01"))
             ];
         case 'quarter':
-            $quarter = ceil($currentMonth / 3);
+            $quarter = isset($_GET['quarter']) ? intval($_GET['quarter']) : ceil($currentMonth / 3);
             $startMonth = ($quarter - 1) * 3 + 1;
             $endMonth = $quarter * 3;
             return [
@@ -279,4 +298,51 @@ function getPreviousPeriodVATData($conn, $dateConditions) {
     $entries = $stmt->fetchAll(PDO::FETCH_ASSOC);
     return calculateVATBreakdown($entries);
 }
+
+function generateMonthlyVATSummary($conn, $dateConditions) {
+    $monthlySummary = [];
+    
+    // Get all months within the date range
+    $start = new DateTime($dateConditions['start_date']);
+    $end = new DateTime($dateConditions['end_date']);
+    $interval = new DateInterval('P1M');
+    $period = new DatePeriod($start, $interval, $end->modify('+1 month'));
+    
+    foreach ($period as $month) {
+        $monthStart = $month->format('Y-m-01');
+        $monthEnd = $month->format('Y-m-t');
+        
+        // Fetch accounting entries for this month
+        $sql = "SELECT 
+                    ae.*,
+                    ac.category_name,
+                    ac.category_type,
+                    ac.vat_percentage as category_vat
+                FROM accounting_entries ae
+                LEFT JOIN accounting_categories ac ON ae.category = ac.category_code
+                WHERE ae.entry_date BETWEEN :start_date AND :end_date
+                ORDER BY ae.entry_date";
+        
+        $stmt = $conn->prepare($sql);
+        $stmt->bindParam(':start_date', $monthStart);
+        $stmt->bindParam(':end_date', $monthEnd);
+        $stmt->execute();
+        
+        $entries = $stmt->fetchAll(PDO::FETCH_ASSOC);
+        $vatBreakdown = calculateVATBreakdown($entries);
+        $totals = calculateVATTotals($vatBreakdown);
+        
+        $monthlySummary[] = [
+            'month' => $month->format('Y-m'),
+            'month_name' => $month->format('F Y'),
+            'payable' => $totals['payable_vat'] ?? 0,
+            'deductible' => $totals['deductible_vat'] ?? 0,
+            'net' => $totals['net_vat'] ?? 0,
+            'turnover' => $totals['taxable_sales'] ?? 0,
+            'vat_breakdown' => $vatBreakdown
+        ];
+    }
+    
+    return $monthlySummary;
+}
 ?>

+ 130 - 3
frontend/src/components/accounting/ALVLaskentaSection.vue

@@ -37,6 +37,9 @@
           <option value="3">Q3 (Heinä-Syyskuu)</option>
           <option value="4">Q4 (Loka-Joulukuu)</option>
         </select>
+        <button class="btn btn-info" @click="toggleMonthlySummary">
+          {{ showMonthlySummary ? 'Normaali raportti' : 'Kuukausikooste' }}
+        </button>
         <button class="btn btn-primary" @click="exportToPDF">Export PDF</button>
         <button class="btn btn-secondary" @click="printReport">Tulosta</button>
       </div>
@@ -59,7 +62,42 @@
         </div>
       </div>
 
+      <!-- Monthly Summary Report -->
+      <div v-if="showMonthlySummary && monthlySummaryData" class="monthly-summary">
+        <h3>Kuukausikooste</h3>
+        <table class="monthly-summary-table">
+          <thead>
+            <tr>
+              <th>Kuukausi</th>
+              <th>ALV maksettava</th>
+              <th>ALV vähennettävä</th>
+              <th>ALV netto</th>
+              <th>Liikevaihto</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="month in monthlySummaryData" :key="month.month">
+              <td>{{ month.month_name }}</td>
+              <td class="summary-card payable">{{ formatCurrency(month.payable) }}</td>
+              <td class="summary-card deductible">{{ formatCurrency(month.deductible) }}</td>
+              <td class="summary-card net">{{ formatCurrency(month.net) }}</td>
+              <td class="summary-card turnover">{{ formatCurrency(month.turnover) }}</td>
+            </tr>
+          </tbody>
+          <tfoot>
+            <tr class="total-row">
+              <td><strong>Yhteensä</strong></td>
+              <td class="summary-card payable"><strong>{{ formatCurrency(monthlySummaryData.reduce((sum, m) => sum + m.payable, 0)) }}</strong></td>
+              <td class="summary-card deductible"><strong>{{ formatCurrency(monthlySummaryData.reduce((sum, m) => sum + m.deductible, 0)) }}</strong></td>
+              <td class="summary-card net"><strong>{{ formatCurrency(monthlySummaryData.reduce((sum, m) => sum + m.net, 0)) }}</strong></td>
+              <td class="summary-card turnover"><strong>{{ formatCurrency(monthlySummaryData.reduce((sum, m) => sum + m.turnover, 0)) }}</strong></td>
+            </tr>
+          </tfoot>
+        </table>
+      </div>
+
       <!-- VAT Calculation Table -->
+      <div v-else>
       <table class="alv-table">
         <thead>
           <tr>
@@ -206,6 +244,7 @@
           </table>
         </div>
       </div>
+      </div>
     </div>
   </div>
 </template>
@@ -232,6 +271,8 @@ export default {
       companyName: '',
       companyYtunnus: '',
       alvData: null,
+      monthlySummaryData: null,
+      showMonthlySummary: false,
       
       // VAT data structure
       vatData: {
@@ -326,13 +367,19 @@ export default {
             period: this.selectedPeriod,
             month: this.selectedMonth,
             quarter: this.selectedQuarter,
-            year: this.selectedYear
+            year: this.selectedYear,
+            report_type: this.showMonthlySummary ? 'monthly_summary' : 'standard'
           }
         })
         
         if (response.data.success) {
-          this.alvData = response.data.data
-          this.updateDataFromAPI(response.data.data)
+          if (this.showMonthlySummary) {
+            console.log('Monthly summary data:', response.data.data.monthly_summary)
+            this.monthlySummaryData = response.data.data.monthly_summary
+          } else {
+            this.alvData = response.data.data
+            this.updateDataFromAPI(response.data.data)
+          }
         } else {
           console.error('API error:', response.data.message)
         }
@@ -343,6 +390,11 @@ export default {
       }
     },
     
+    toggleMonthlySummary() {
+      this.showMonthlySummary = !this.showMonthlySummary
+      this.loadALVLaskenta()
+    },
+    
     async loadCompanyDetails() {
       try {
         const response = await api.get('/company.php')
@@ -620,4 +672,79 @@ export default {
     display: none;
   }
 }
+
+.monthly-summary {
+  margin: 20px 0;
+}
+
+.monthly-summary h3 {
+  margin: 0 0 15px 0;
+  color: #333;
+  border-bottom: 2px solid #333;
+  padding-bottom: 10px;
+}
+
+.monthly-summary-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin-bottom: 20px;
+  background: white;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+.monthly-summary-table th,
+.monthly-summary-table td {
+  padding: 12px;
+  text-align: right;
+  border: 1px solid #ddd;
+}
+
+.monthly-summary-table th:first-child,
+.monthly-summary-table td:first-child {
+  text-align: left;
+  font-weight: 500;
+  color: #333 !important;
+}
+
+.monthly-summary-table th {
+  background-color: #f8f9fa;
+  font-weight: 600;
+  color: #333;
+}
+
+.monthly-summary-table .total-row {
+  background-color: #f8f9fa;
+  font-weight: 600;
+  border-top: 2px solid #333;
+}
+
+.monthly-summary-table .total-row td {
+  font-weight: 600;
+}
+
+.summary-card.payable {
+  color: #d32f2f;
+  font-weight: 500;
+}
+
+.summary-card.deductible {
+  color: #2e7d32;
+  font-weight: 500;
+}
+
+.summary-card.net {
+  color: #1976d2;
+  font-weight: 500;
+}
+
+.summary-card.turnover {
+  color: #6a1b9a;
+  font-weight: 500;
+}
+
+@media print {
+  .monthly-summary-table {
+    font-size: 10pt;
+  }
+}
 </style>