- News
- Press Release
- Tỷ giá trung tâm
- Tỷ giá tham khảo tại giữa đồng Việt Nam và các loại ngoại tệ tại Cục Quản lý ngoại hối
- Tỷ giá tính chéo của Đồng Việt Nam với một số ngoại tệ để xác định giá tính thuế
- Lãi suất NHNN quy định
- Lãi suất thị trường liên ngân hàng
- Statistics
- CPI
- Legal Documents
- Monetary Policy
- Payment & Treasury
- Money Issuance
- Quản lý hoạt động ngoại hối và hoạt động kinh doanh vàng
- Cải cách hành chính
- Diễn đàn NHNN
- About SBV
- News
- Press Release
- Tỷ giá trung tâm
- Tỷ giá tham khảo tại giữa đồng Việt Nam và các loại ngoại tệ tại Cục Quản lý ngoại hối
- Tỷ giá tính chéo của Đồng Việt Nam với một số ngoại tệ để xác định giá tính thuế
- Lãi suất NHNN quy định
- Lãi suất thị trường liên ngân hàng
- Statistics
- CPI
- Legal Documents
- Monetary Policy
- Payment & Treasury
- Money Issuance
- Quản lý hoạt động ngoại hối và hoạt động kinh doanh vàng
- Cải cách hành chính
- Diễn đàn NHNN
- About SBV
HOẠT ĐỘNG TỔ CHỨC TÍN DỤNG
RESEARCH - DISCUSSION
Developing an integrated digital ecosystem connecting banking with other sectors
In the coming period, the banking sector will continue to implement cross-sectoral cooperation: integrating, connecting, and sharing information between the banking sector and other industries to expand the digital ecosystem and develop digital banking and payment services. This will help form an interconnected digital ecosystem, creating favorable conditions for people and businesses to access services quickly, safely, and effectively.
Cross-border payments: An inevitable trend in the context of international integration and digital transformation
To promote cross-border payment connectivity within the region and globally, and to meet the needs of individuals and businesses for fast, secure, and convenient transactions, it is necessary to establish a comprehensive legal framework, synchronized modern technical infrastructure, sustainable and secure payment technology platforms, and stronger inter-sectoral coordination and international cooperation.
The following has evaluated to null or missing:
==> article.getDisplayDate() [in template "29795641980326#20120#139054" at line 7, column 19]
----
Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign dt = article.getDisplayDate() [in template "29795641980326#20120#139054" at line 7, column 5]
----
1<#if entries?has_content>
2
3 <#assign sortedEntries = [] />
4
5 <#list entries as entry>
6 <#assign article = entry.getAssetRenderer().getArticle() />
7 <#assign dt = article.getDisplayDate() />
8
9 <#assign sortedEntries = sortedEntries + [{
10 "entry": entry,
11 "date": dt
12 }] />
13 </#list> <#-- ✅ PHẢI CÓ DÒNG NÀY -->
14
15 <#assign entries = sortedEntries?sort_by("date")?map(item -> item.entry) />
16<#-- GROUP theo quý, lấy bài mới nhất -->
17<#assign quarterMap = {} />
18
19<#list entries as entry>
20 <#assign dt = entry.getAssetRenderer().getArticle().getDisplayDate() />
21 <#assign m = dt?string("M")?number />
22 <#assign y = dt?string("yyyy") />
23
24 <#if m <= 3>
25 <#assign q = "I">
26 <#elseif m <= 6>
27 <#assign q = "II">
28 <#elseif m <= 9>
29 <#assign q = "III">
30 <#else>
31 <#assign q = "IV">
32 </#if>
33
34 <#assign key = y + "-" + q />
35
36<#if !quarterMap[key]?? || (dt?long > quarterMap[key].date?long)>
37 <#assign quarterMap = quarterMap + {
38 key: {
39 "entry": entry,
40 "date": dt
41 }
42 } />
43 </#if>
44</#list>
45
46<#assign entries = quarterMap?values?sort_by("date")?map(item -> item.entry) />
47<#-- CHỈ LẤY 4 QUÝ MỚI NHẤT -->
48<#if entries?size gt 4>
49 <#assign entries = entries[entries?size - 4 .. entries?size - 1] />
50</#if>
51
52<#assign lastEntry = entries[entries?size - 1] />
53<#assign dtLast = lastEntry.getAssetRenderer().getArticle().getDisplayDate() />
54
55<#assign monthLast = dtLast?string("M")?number />
56
57<#if monthLast <= 3>
58 <#assign quarterLast = "I">
59<#elseif monthLast <= 6>
60 <#assign quarterLast = "II">
61<#elseif monthLast <= 9>
62 <#assign quarterLast = "III">
63<#else>
64 <#assign quarterLast = "IV">
65</#if>
66
67<#assign yearLast = dtLast?string("yyyy") />
68
69
70 <div class="max-[1170px]:w-[calc(100%/2-12px)] max-[768px]:w-[calc(100%/2-4px)] max-[768px]:p-2 max-[650px]:w-full max-[650px]:px-0 sbv-chart">
71 <#if currentURL?contains("/vi/")>
72 <div class="flex flex-col space-y-[4px] mb-3">
73 <a href="/can-can-thanh-toan-quoc-te" class="text-[#000000] text-[20px] leading-[1.15] font-bold uppercase">
74 CÁN CÂN THANH TOÁN QUỐC TẾ
75 </a>
76 <span class="text-[var(--unnamed-color-000000)] leading-[21px] text-[16px]">QUÝ ${quarterLast} NĂM ${yearLast} (Triệu USD)</span>
77 </div>
78 <#else>
79 <div class="flex flex-col space-y-[4px] mb-2">
80 <a style="text-align: start" href="/can-can-thanh-toan-quoc-te" class="text-[#000000] text-[20px] leading-[1.15] font-bold uppercase">
81 Balance of International Payment
82 </a>
83 <span class="text-[var(--unnamed-color-000000)] leading-[21px] text-[16px]">QUARTER ${quarterLast} YEAR ${yearLast} (In million of USD)</span>
84 </div>
85 </#if>
86 <div class="w-[370px] h-[270px] max-[1170px]:w-full max-[1170px]:h-[370px] bg-white p-1">
87 <!-- Bar chart would be rendered here -->
88 <canvas id="statChart" width="400" height="300"></canvas>
89 </div>
90 <div class="text-end mt-2">
91 <span class="text-[#9D1B43] rounded-full flex justify-start items-center space-x-[6px]">
92 <#if currentURL?contains("/vi/")>
93 <a href="/can-can-thanh-toan-quoc-te" class="text-[#9D1B43] inline-block text-[14px] leading-[1.5] space-x-[6px]">
94 Xem chi tiết <i class="fa-solid fa-caret-right"></i>
95 </a>
96 <#else>
97 <a href="/can-can-thanh-toan-quoc-te" class="text-[#9D1B43] inline-block text-[14px] leading-[1.5] space-x-[6px]">
98 Details <i class="fa-solid fa-caret-right"></i>
99 </a>
100 </#if>
101
102 </div>
103 </div>
104<style>
105 .sbv-chart .text-end a{color: #9D1B43;}
106 .sbv-chart .text-end a:hover{color: var(--btn-link-hover-color);}
107</style>
108<script>
109// Khi DOM xong thì build chart
110document.addEventListener("DOMContentLoaded", function() {
111 // 3) Tạo mảng label: [ "QI/2024", "QII/2024", ... ]
112const labels = [
113 <#list entries as curEntry>
114
115 <#assign dt = curEntry.getAssetRenderer().getArticle().getDisplayDate() />
116 <#assign m = dt?string("M")?number />
117
118 <#if m <= 3>
119 <#assign q = "I">
120 <#elseif m <= 6>
121 <#assign q = "II">
122 <#elseif m <= 9>
123 <#assign q = "III">
124 <#else>
125 <#assign q = "IV">
126 </#if>
127
128 <#assign label = "Q" + q + "/" + dt?string("yyyy") />
129
130 "${label}"<#if curEntry_has_next>,</#if>
131
132 </#list>
133];
134
135 // Mỗi mảng số liệu build tách biệt:
136const canCanVangLai = [
137 <#list entries as e>
138 <#assign ddm = e.getAssetRenderer()
139 .getDDMFormValuesReader()
140 .getDDMFormValues()
141 .getDDMFormFieldValuesMap() />
142
143 <#assign v = 0 />
144
145 <#if ddm["canCanVangLai"]?has_content>
146 <#assign raw = ddm["canCanVangLai"][0].getValue().getString(locale)!"" />
147
148 <#if raw?has_content>
149 <#-- xử lý format số nếu có dấu -->
150 <#assign raw = raw?replace(",", ".") />
151 <#assign v = raw?number />
152 </#if>
153 </#if>
154
155 ${v}<#if e_has_next>,</#if>
156 </#list>
157];
158
159const canCanVon = [
160 <#list entries as e>
161 <#assign ddm = e.getAssetRenderer()
162 .getDDMFormValuesReader()
163 .getDDMFormValues()
164 .getDDMFormFieldValuesMap() />
165
166 <#assign v = 0 />
167
168 <#if ddm["canCanVon"]?has_content>
169 <#assign raw = ddm["canCanVon"][0].getValue().getString(locale)!"" />
170
171 <#if raw?has_content>
172 <#assign raw = raw?replace(",", ".") />
173 <#assign v = raw?number />
174 </#if>
175 </#if>
176
177 ${v}<#if e_has_next>,</#if>
178 </#list>
179];
180 const canCanTaiChinh = [
181 <#list entries as e>
182 <#assign ddm = e.getAssetRenderer()
183 .getDDMFormValuesReader()
184 .getDDMFormValues()
185 .getDDMFormFieldValuesMap() />
186 <#assign v = 0 />
187 <#if ddm["canCanTaiChinh"]?has_content>
188 <#assign v = ddm["canCanTaiChinh"][0].getValue().getString(locale)?number />
189 </#if>
190 ${v}<#if e_has_next>,</#if>
191 </#list>
192 ];
193
194 const loiVaSaiSot = [
195 <#list entries as e>
196 <#assign ddm = e.getAssetRenderer()
197 .getDDMFormValuesReader()
198 .getDDMFormValues()
199 .getDDMFormFieldValuesMap() />
200 <#assign v = 0 />
201 <#if ddm["loiVaSaiSot"]?has_content>
202 <#assign v = ddm["loiVaSaiSot"][0].getValue().getString(locale)?number />
203 </#if>
204 ${v}<#if e_has_next>,</#if>
205 </#list>
206 ];
207
208 const canCanTongThe = [
209 <#list entries as e>
210 <#assign ddm = e.getAssetRenderer()
211 .getDDMFormValuesReader()
212 .getDDMFormValues()
213 .getDDMFormFieldValuesMap() />
214 <#assign v = 0 />
215 <#if ddm["canCanTongThe"]?has_content>
216 <#assign v = ddm["canCanTongThe"][0].getValue().getString(locale)?number />
217 </#if>
218 ${v}<#if e_has_next>,</#if>
219 </#list>
220 ];
221
222 const duTruLienQuan = [
223 <#list entries as e>
224 <#assign ddm = e.getAssetRenderer()
225 .getDDMFormValuesReader()
226 .getDDMFormValues()
227 .getDDMFormFieldValuesMap() />
228 <#assign v = 0 />
229 <#if ddm["duTruVaCacHangMucLien"]?has_content>
230 <#assign v = ddm["duTruVaCacHangMucLien"][0].getValue().getString(locale)?number />
231 </#if>
232 ${v}<#if e_has_next>,</#if>
233 </#list>
234 ];
235
236 // Vẽ chart
237 const ctx = document.getElementById("statChart").getContext("2d");
238 new Chart(ctx, {
239 type: "line",
240 data: {
241 labels: labels,
242 datasets: [
243 <#if currentURL?contains("/vi/")>
244 { label: "Cán cân vãng lai", data: canCanVangLai, borderColor: "#6f42c1", pointBackgroundColor: "#6f42c1", fill: false, tension: 0.3, borderWidth: 1 },
245 { label: "Cán cân vốn", data: canCanVon, borderColor: "#fd7e14", pointBackgroundColor: "#fd7e14", fill: false, tension: 0.3, borderWidth: 1 },
246 { label: "Cán cân tài chính", data: canCanTaiChinh, borderColor: "#0d6efd", pointBackgroundColor: "#0d6efd", fill: false, tension: 0.3, borderWidth: 1 },
247 { label: "Lỗi và sai sót", data: loiVaSaiSot, borderColor: "#198754", pointBackgroundColor: "#198754", fill: false, tension: 0.3, borderWidth: 1 },
248 { label: "Cán cân tổng thể", data: canCanTongThe, borderColor: "#6610f2", pointBackgroundColor: "#6610f2", fill: false, tension: 0.3, borderWidth: 1 },
249 { label: "Dự trữ & hạng mục liên quan",data: duTruLienQuan, borderColor: "#0dcaf0", pointBackgroundColor: "#0dcaf0", fill: false, tension: 0.3, borderWidth: 1 }
250 <#else>
251 { label: "Current Account", data: canCanVangLai, borderColor: "#6f42c1", pointBackgroundColor: "#6f42c1", fill: false, tension: 0.3, borderWidth: 1 },
252 { label: "Capital Account", data: canCanVon, borderColor: "#fd7e14", pointBackgroundColor: "#fd7e14", fill: false, tension: 0.3, borderWidth: 1 },
253 { label: "Financial account", data: canCanTaiChinh, borderColor: "#0d6efd", pointBackgroundColor: "#0d6efd", fill: false, tension: 0.3, borderWidth: 1 },
254 { label: "Net Errors and Omissions", data: loiVaSaiSot, borderColor: "#198754", pointBackgroundColor: "#198754", fill: false, tension: 0.3, borderWidth: 1 },
255 { label: "Overall balance", data: canCanTongThe, borderColor: "#6610f2", pointBackgroundColor: "#6610f2", fill: false, tension: 0.3, borderWidth: 1 },
256 { label: "Reserve and related items",data: duTruLienQuan, borderColor: "#0dcaf0", pointBackgroundColor: "#0dcaf0", fill: false, tension: 0.3, borderWidth: 1 }
257 </#if>
258
259 ]
260 },
261 options: {
262 responsive: true,
263 plugins: {
264 tooltip: {
265 callbacks: {
266 title: function() {
267 return [];
268 },
269 label: function(context) {
270 const label = context.dataset.label || '';
271 const time = context.label || '';
272 const value = context.formattedValue || '';
273
274 <#if currentURL?contains("/vi/")>
275 return [
276 "Chỉ tiêu: " + label,
277 "Thời gian: " + time,
278 "Giá trị: " + value + " Triệu USD"
279 ];
280 <#else>
281 return [
282 "Standard: " + label,
283 "Time: " + time,
284 "Value: " + value + " Million of USD"
285 ];
286 </#if>
287
288 }
289 }
290},
291legend: {
292 position: 'top',
293 labels: {
294 usePointStyle: true,
295 pointStyle: 'circle',
296 boxWidth: 5,
297 boxHeight: 5,
298 padding: 10,
299 color: "#000000",
300 font: { size: 10 },
301 generateLabels: function(chart) {
302 const items = Chart.defaults.plugins.legend.labels.generateLabels(chart);
303 // Group items thành mảng con 3 phần tử
304 const grouped = [];
305 for (let i = 0; i < items.length; i += 3) {
306 grouped.push(items.slice(i, i + 3));
307 }
308 // Flatten lại nhưng thêm dấu xuống dòng vào cuối mỗi dòng (hack wrap)
309 return grouped.flatMap((group, idx, arr) => {
310 if (idx < arr.length - 1) {
311 group[group.length - 1].text += '\n';
312 }
313 return group;
314 });
315 }
316 }
317},
318 title: {
319 display: false,
320 text: "DỮ LIỆU THỐNG KÊ\nQUÝ III NĂM 2024 (Triệu USD)",
321 font: { size: 16, weight: "bold" }
322 }
323 },
324 scales: {
325 x: {
326 ticks: {
327 color: '#000000'
328 },
329 title: { display: true,
330 <#if currentURL?contains("/vi/")>
331 text: "Thời gian: Quý/Năm",
332 <#else>
333 text: "Time: Quarter/Year",
334 </#if>
335 align: 'end',
336 color: "#000000",
337 font: { weight: "bold" } }
338 },
339 y: {
340 ticks: {
341 color: '#000000'
342 },
343 title: {
344 display: true,
345 <#if currentURL?contains("/vi/")>
346 text: "Triệu USD",
347 <#else>
348 text: "Million of USD",
349 </#if>
350 position: 'top',
351 align: 'end',
352 color: "#000000",
353 font: { weight: "bold" } },
354 beginAtZero: false
355 }
356 }
357 }
358 });
359});
360</script>
361 </#if>