added 4 new asset report
This commit is contained in:
parent
4902222832
commit
aa22ffeef3
|
|
@ -0,0 +1,268 @@
|
||||||
|
{
|
||||||
|
"cadastral_regions": [
|
||||||
|
{
|
||||||
|
"order_number": "1",
|
||||||
|
"region_name": "Abşeron—Qobustan",
|
||||||
|
"description": "Abşeron rayonu, Hacıqabul rayonunun Nəvahi-Atbulaq massivi, Siyəzən və Xızı rayonlarının düzən torpaqları, habelə Bakı və Sumqayıt şəhərlərinin mövcud hüdudundan kənarda olan kənd təsərrüfatı təyinatlı torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 85,
|
||||||
|
"II": 70,
|
||||||
|
"III": 60,
|
||||||
|
"IV": 25,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "2",
|
||||||
|
"region_name": "Şabran—Xaçmaz",
|
||||||
|
"description": "Xaçmaz rayonu, Şabran, Quba, Qusar və Siyəzən rayonlarının düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 121,
|
||||||
|
"II": 89,
|
||||||
|
"III": 57,
|
||||||
|
"IV": 35,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "3",
|
||||||
|
"region_name": "Qanıx—Türyançay",
|
||||||
|
"description": "Balakən, Qax, Zaqatala, Şəki, Oğuz və Qəbələ rayonlarının düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 180,
|
||||||
|
"II": 115,
|
||||||
|
"III": 50,
|
||||||
|
"IV": 15,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "4",
|
||||||
|
"region_name": "Şəki-Zaqatala",
|
||||||
|
"description": "Balakən, Qax, Zaqatala, Şəki, Oğuz və Qəbələ rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 200,
|
||||||
|
"II": 150,
|
||||||
|
"III": 90,
|
||||||
|
"IV": 25,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "5",
|
||||||
|
"region_name": "Qusar—Qonaqkənd",
|
||||||
|
"description": "Qusar, Quba, Şabran, Siyəzən və Xızı rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 40,
|
||||||
|
"II": 20,
|
||||||
|
"III": 10,
|
||||||
|
"IV": 5,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "5a",
|
||||||
|
"region_name": "Xınalıq—Xaltan",
|
||||||
|
"description": "Qusar və Quba rayonlarının orta və yüksək dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 38,
|
||||||
|
"II": 24,
|
||||||
|
"III": 23,
|
||||||
|
"IV": 8,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "6",
|
||||||
|
"region_name": "Dağ—Şirvan",
|
||||||
|
"description": "Şamaxı, İsmayıllı rayonları, Ağsu və Göyçay rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 66,
|
||||||
|
"II": 50,
|
||||||
|
"III": 33,
|
||||||
|
"IV": 19,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "6a",
|
||||||
|
"region_name": "Qobustan—Xilmilli",
|
||||||
|
"description": "Qobustan rayonunun dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 58,
|
||||||
|
"II": 44,
|
||||||
|
"III": 29,
|
||||||
|
"IV": 16,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "7",
|
||||||
|
"region_name": "Gəncə—Qazax",
|
||||||
|
"description": "Samux rayonu, Goranboy, Göygöl, Tovuz, Ağstafa, Şəmkir və Qazax rayonlarının düzən torpaqları, habelə Gəncə və Naftalan şəhərlərinin mövcud hüdudundan kənarda olan kənd təsərrüfatı təyinatlı torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 60,
|
||||||
|
"II": 45,
|
||||||
|
"III": 38,
|
||||||
|
"IV": 26,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "8",
|
||||||
|
"region_name": "Mil—Qarabağ",
|
||||||
|
"description": "Bərdə, Ağcəbədi, Beyləqan, Tərtər rayonları, Ağdam, keçmiş Ağdərə rayonunun ərazisi və Xocavəndin düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 127,
|
||||||
|
"II": 102,
|
||||||
|
"III": 80,
|
||||||
|
"IV": 45,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "9",
|
||||||
|
"region_name": "Arazboyu",
|
||||||
|
"description": "Füzuli, Zəngilan və Cəbrayıl rayonlarının düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 56,
|
||||||
|
"II": 41,
|
||||||
|
"III": 37,
|
||||||
|
"IV": 20,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "10",
|
||||||
|
"region_name": "Daşkəsən—Gədəbəy",
|
||||||
|
"description": "Gədəbəy, Daşkəsən rayonları, Goranboy, Göygöl, Şəmkir, Tovuz, Ağstafa və Qazax rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 42,
|
||||||
|
"II": 35,
|
||||||
|
"III": 26,
|
||||||
|
"IV": 16,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "11",
|
||||||
|
"region_name": "Laçın—Qubadlı",
|
||||||
|
"description": "Kəlbəcər, Laçın, Qubadlı rayonları və Zəngilan rayonunun dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 29,
|
||||||
|
"II": 23,
|
||||||
|
"III": 17,
|
||||||
|
"IV": 11,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "12",
|
||||||
|
"region_name": "Dağ—Qarabağ",
|
||||||
|
"description": "Şuşa, Xocalı rayonları, Xocavənd, keçmiş Ağdərə rayonunun ərazisi, habelə Ağdam, Füzuli, Cəbrayıl rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 42,
|
||||||
|
"II": 30,
|
||||||
|
"III": 27,
|
||||||
|
"IV": 20,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "13",
|
||||||
|
"region_name": "Muğan-Salyan",
|
||||||
|
"description": "Salyan, Saatlı, Sabirabad, İmişli, Neftçala və Biləsuvar rayonları, Hacıqabulun Kürqırağı düzən hissəsi, habelə Şirvan şəhərinin mövcud hüdudundan kənarda olan kənd təsərrüfatı təyinatlı torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 98,
|
||||||
|
"II": 92,
|
||||||
|
"III": 75,
|
||||||
|
"IV": 33,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "14",
|
||||||
|
"region_name": "Aran—Şirvan",
|
||||||
|
"description": "Kürdəmir, Zərdab, Ucar, Yevlax, Ağdaş rayonları, Ağsu, Göyçay rayonlarının düzən torpaqları və Mingəçevir şəhərinin mövcud hüdudundan kənarda olan kənd təsərrüfatı təyinatlı torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 84,
|
||||||
|
"II": 75,
|
||||||
|
"III": 65,
|
||||||
|
"IV": 30,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "15",
|
||||||
|
"region_name": "Lənkəran—Astara",
|
||||||
|
"description": "Lənkəran, Masallı və Astara rayonlarının düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 125,
|
||||||
|
"II": 117,
|
||||||
|
"III": 92,
|
||||||
|
"IV": 50,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "16",
|
||||||
|
"region_name": "Cəlilabad",
|
||||||
|
"description": "Cəlilabad rayonunun düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 73,
|
||||||
|
"II": 59,
|
||||||
|
"III": 47,
|
||||||
|
"IV": null,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "16a",
|
||||||
|
"region_name": "Üçtəpə—Təzəkənd",
|
||||||
|
"description": "Cəlilabad rayonunun dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 60,
|
||||||
|
"II": 48,
|
||||||
|
"III": 58,
|
||||||
|
"IV": null,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "17",
|
||||||
|
"region_name": "Lerik— Yardımlı",
|
||||||
|
"description": "Lerik, Yardımlı rayonları, Masallı, Lənkəran və Astara rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 35,
|
||||||
|
"II": 24,
|
||||||
|
"III": 18,
|
||||||
|
"IV": null,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "18",
|
||||||
|
"region_name": "Şərur—Ordubad",
|
||||||
|
"description": "Şərur, Sədərək, Babək, Ordubad və Culfa rayonlarının düzən torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 53,
|
||||||
|
"II": 40,
|
||||||
|
"III": 31,
|
||||||
|
"IV": 20,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"order_number": "19",
|
||||||
|
"region_name": "Şahbuz—Paraqaçay",
|
||||||
|
"description": "Şahbuz rayonu, Şərur, Sədərək, Babək, Ordubad, Culfa rayonlarının dağ torpaqları",
|
||||||
|
"quality_groups": {
|
||||||
|
"I": 24,
|
||||||
|
"II": 18,
|
||||||
|
"III": 12,
|
||||||
|
"IV": 8,
|
||||||
|
"V": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"industrial_land_regions": [
|
||||||
|
{
|
||||||
|
"settlement_name": "Bakı",
|
||||||
|
"land_purpose_rates": {
|
||||||
|
"Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xid-ti və dig. xüs. təy-tlı sahələr": {
|
||||||
|
"up_to_10000_sqm": 10,
|
||||||
|
"above_10000_sqm": 20
|
||||||
|
},
|
||||||
|
"Yaşayış fondları, həyətyanı və bağsahələri üzrə sahələr": {
|
||||||
|
"up_to_10000_sqm": 0.6,
|
||||||
|
"above_10000_sqm": 1.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"settlement_name": "Gəncə, Sumqayıt, Xırdalan, Abşeron",
|
||||||
|
"land_purpose_rates": {
|
||||||
|
"Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xid-ti və dig. xüs. təy-tlı sahələr": {
|
||||||
|
"up_to_10000_sqm": 8,
|
||||||
|
"above_10000_sqm": 16
|
||||||
|
},
|
||||||
|
"Yaşayış fondları, həyətyanı və bağsahələri üzrə sahələr": {
|
||||||
|
"up_to_10000_sqm": 0.5,
|
||||||
|
"above_10000_sqm": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"settlement_name": "Digər şəhərlər (rayon tabeliyində olan şəhərlər istisna olmaqla), Rayon mərkəzləri",
|
||||||
|
"land_purpose_rates": {
|
||||||
|
"Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xid-ti və dig. xüs. təy-tlı sahələr": {
|
||||||
|
"up_to_10000_sqm": 4,
|
||||||
|
"above_10000_sqm": 8
|
||||||
|
},
|
||||||
|
"Yaşayış fondları, həyətyanı və bağsahələri üzrə sahələr": {
|
||||||
|
"up_to_10000_sqm": 0.3,
|
||||||
|
"above_10000_sqm": 0.6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"settlement_name": "Rayon tabeçiliyində olan şəhərlərdə, qəsəbələrdə və kəndlərdə (Bakı və Sumqayıt şəhərlərinin qəsəbə və kəndləri istisna olmaqla)",
|
||||||
|
"land_purpose_rates": {
|
||||||
|
"Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xid-ti və dig. xüs. təy-tlı sahələr": {
|
||||||
|
"up_to_10000_sqm": 2,
|
||||||
|
"above_10000_sqm": 4
|
||||||
|
},
|
||||||
|
"Yaşayış fondları, həyətyanı və bağsahələri üzrə sahələr": {
|
||||||
|
"up_to_10000_sqm": 0.1,
|
||||||
|
"above_10000_sqm": 0.2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -462,7 +462,7 @@
|
||||||
"parent_tax_article": "ƏDV-dən azad olunan əməliyyatlar"
|
"parent_tax_article": "ƏDV-dən azad olunan əməliyyatlar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 164.1.47-ci maddəsinə əsasən bina tikintisi fəaliyyəti ilə məşğul olan şəxslər tərəfindən tikilən binanın yaşayış sahəsinin dövlətə ayrılan hissəsi üzrə dövriyyələr",
|
"article_name": "VM-nin 164.1.47-ci maddəsinə əsasən bina tikintisi fəaliyyəti ilə məşğul olan şəxslər tərəfindən tikilən binanın yaşayış sahəsinin dövlətə ayrılan hissəsi üzrə dövriyyələr",
|
||||||
"declaration": "Declaration of value added tax",
|
"declaration": "Declaration of value added tax",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -627,7 +627,7 @@
|
||||||
"parent_tax_article": "ƏDV-dən azad olunan əməliyyatlar"
|
"parent_tax_article": "ƏDV-dən azad olunan əməliyyatlar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 164.1.58-ci maddəsinə əsasən özəl baytarlıq xidmətlərinin göstərilməsi",
|
"article_name": "VM-nin 164.1.58-ci maddəsinə əsasən özəl baytarlıq xidmətlərinin göstərilməsi",
|
||||||
"declaration": "Declaration of value added tax",
|
"declaration": "Declaration of value added tax",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -825,200 +825,200 @@
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.523700",
|
"modified": "2025-08-26 20:43:40.523700",
|
||||||
"name": "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.525457",
|
"modified": "2025-08-26 20:43:40.525457",
|
||||||
"name": "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.527144",
|
"modified": "2025-08-26 20:43:40.527144",
|
||||||
"name": "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.528823",
|
"modified": "2025-08-26 20:43:40.528823",
|
||||||
"name": "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.530475",
|
"modified": "2025-08-26 20:43:40.530475",
|
||||||
"name": "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 199.5-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.532116",
|
"modified": "2025-08-26 20:43:40.532116",
|
||||||
"name": "Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.533717",
|
"modified": "2025-08-26 20:43:40.533717",
|
||||||
"name": "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.535622",
|
"modified": "2025-08-26 20:43:40.535622",
|
||||||
"name": "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.537347",
|
"modified": "2025-08-26 20:43:40.537347",
|
||||||
"name": "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.538669",
|
"modified": "2025-08-26 20:43:40.538669",
|
||||||
"name": "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.539938",
|
"modified": "2025-08-26 20:43:40.539938",
|
||||||
"name": "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.541241",
|
"modified": "2025-08-26 20:43:40.541241",
|
||||||
"name": "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.542614",
|
"modified": "2025-08-26 20:43:40.542614",
|
||||||
"name": "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.544045",
|
"modified": "2025-08-26 20:43:40.544045",
|
||||||
"name": "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 199.18-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.545318",
|
"modified": "2025-08-26 20:43:40.545318",
|
||||||
"name": "Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.546852",
|
"modified": "2025-08-26 20:43:40.546852",
|
||||||
"name": "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.548331",
|
"modified": "2025-08-26 20:43:40.548331",
|
||||||
"name": "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən:",
|
"article_name": "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən",
|
||||||
"declaration": "Property tax return",
|
"declaration": "Property tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
"is_group": 0,
|
"is_group": 0,
|
||||||
"modified": "2025-08-26 20:43:40.549825",
|
"modified": "2025-08-26 20:43:40.549825",
|
||||||
"name": "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən:",
|
"name": "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən",
|
||||||
"old_parent": null,
|
"old_parent": null,
|
||||||
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
"parent_tax_article": "Vergidən azad olunan əsas vəsaitlərin dəyəri haqqında məlumat"
|
||||||
},
|
},
|
||||||
|
|
@ -1045,7 +1045,7 @@
|
||||||
"parent_tax_article": "Gəlirlər"
|
"parent_tax_article": "Gəlirlər"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "VM-nin 119.2-ci maddəsinə əsasən qanunvericiliklə müəyyən edilmiş normalar daxilində çəkilən xərclər\t",
|
"article_name": "VM-nin 119.2-ci maddəsinə əsasən qanunvericiliklə müəyyən edilmiş normalar daxilində çəkilən xərclər",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1078,7 +1078,7 @@
|
||||||
"parent_tax_article": "Xərclər"
|
"parent_tax_article": "Xərclər"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 109.8-ci maddəsinə əsasən xərclər",
|
"article_name": "VM-nin 109.8-ci maddəsinə əsasən xərclər",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1122,7 +1122,7 @@
|
||||||
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 227.1-ci maddəsinə əsasən azaldılmalı verginin məbləği",
|
"article_name": "VM-nin 227.1-ci maddəsinə əsasən azaldılmalı verginin məbləği",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1144,7 +1144,7 @@
|
||||||
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 114.4-cü maddəsi ilə hesablanmış, lakin növbəti illərdə nəzərə alınacaq amortizasiya məbləği\t",
|
"article_name": "VM-nin 114.4-cü maddəsi ilə hesablanmış, lakin növbəti illərdə nəzərə alınacaq amortizasiya məbləği",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1155,7 +1155,7 @@
|
||||||
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 115.1-ci maddəsi ilə hesablanmış, lakin növbəti illərdə nəzərə alınacaq təmir xərclərinin məbləği",
|
"article_name": "VM-nin 115.1-ci maddəsi ilə hesablanmış, lakin növbəti illərdə nəzərə alınacaq təmir xərclərinin məbləği",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1166,7 +1166,7 @@
|
||||||
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
"parent_tax_article": "Hesabat dövrü üçün verginin hesablanması"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVM-nin 109.2-ci maddəsinə əsasən gəlirdən çıxılmayan xərclər",
|
"article_name": "VM-nin 109.2-ci maddəsinə əsasən gəlirdən çıxılmayan xərclər",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1199,7 +1199,7 @@
|
||||||
"parent_tax_article": "Mənfəət Vergisi"
|
"parent_tax_article": "Mənfəət Vergisi"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.1-ci maddəsinə əsasən xeyriyyə təşkilatlarının gəliri — sahibkarlıq fəaliyyətindən əldə etdikləri gəlirdən başqa",
|
"article_name": "Vergi Məcəlləsinin 106.1.1-ci maddəsinə əsasən xeyriyyə təşkilatlarının gəliri — sahibkarlıq fəaliyyətindən əldə etdikləri gəlirdən başqa",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1221,7 +1221,7 @@
|
||||||
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.3-cü maddəsinə əsasən beynəlxalq, dövlətlərarası və hökumətlərarası təşkilatların gəlirləri — sahibkarlıq fəaliyyətindən əldə etdikləri gəlirdən başqa",
|
"article_name": "Vergi Məcəlləsinin 106.1.3-cü maddəsinə əsasən beynəlxalq, dövlətlərarası və hökumətlərarası təşkilatların gəlirləri — sahibkarlıq fəaliyyətindən əldə etdikləri gəlirdən başqa",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1254,7 +1254,7 @@
|
||||||
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.6-cı maddəsinə əsasən alınmış sığorta ödənişləri (həmin sığorta hadisəsi ilə əlaqədar zərərə aid edilən məbləğlərdən başqa)",
|
"article_name": "Vergi Məcəlləsinin 106.1.6-cı maddəsinə əsasən alınmış sığorta ödənişləri (həmin sığorta hadisəsi ilə əlaqədar zərərə aid edilən məbləğlərdən başqa)",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1298,7 +1298,7 @@
|
||||||
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.11-ci maddəsinə əsasən neft-qaz ehtiyatlarının kəşfiyyatı, işlənməsi və hasilatın pay bölgüsü, ixrac boru kəmərləri haqqında və bu qəbildən olan digər sazişlərə uyğun olaraq əsas fondların, daşınar əmlakın və digər aktivlərin hər hansı şəkildə həmin sazişlərdə Azərbaycan Respublikasını təmsil edən tərəfə təqdim edilməsi üzrə əməliyyatlar",
|
"article_name": "Vergi Məcəlləsinin 106.1.11-ci maddəsinə əsasən neft-qaz ehtiyatlarının kəşfiyyatı, işlənməsi və hasilatın pay bölgüsü, ixrac boru kəmərləri haqqında və bu qəbildən olan digər sazişlərə uyğun olaraq əsas fondların, daşınar əmlakın və digər aktivlərin hər hansı şəkildə həmin sazişlərdə Azərbaycan Respublikasını təmsil edən tərəfə təqdim edilməsi üzrə əməliyyatlar",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1331,7 +1331,7 @@
|
||||||
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.16-cı maddəsinə əsasən «Torpaqların dövlət ehtiyacları üçün alınması haqqında» Azərbaycan Respublikasının Qanununa əsasən hüquqi şəxslərə ödənilən kompensasiya",
|
"article_name": "Vergi Məcəlləsinin 106.1.16-cı maddəsinə əsasən «Torpaqların dövlət ehtiyacları üçün alınması haqqında» Azərbaycan Respublikasının Qanununa əsasən hüquqi şəxslərə ödənilən kompensasiya",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1430,7 +1430,7 @@
|
||||||
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
"parent_tax_article": "Gəlirlər üzrə azadolmalar barədə məlumat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 106.1.30-cu maddəsinə əsasən vəkillər və vəkil qurumları tərəfindən order markasının əldə edilməsi ilə bağlı Azərbaycan Respublikasının Vəkillər Kollegiyasına edilən ödənişlər",
|
"article_name": "Vergi Məcəlləsinin 106.1.30-cu maddəsinə əsasən vəkillər və vəkil qurumları tərəfindən order markasının əldə edilməsi ilə bağlı Azərbaycan Respublikasının Vəkillər Kollegiyasına edilən ödənişlər",
|
||||||
"declaration": "Income tax return",
|
"declaration": "Income tax return",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
@ -1683,7 +1683,7 @@
|
||||||
"parent_tax_article": "Verginin hesablanması"
|
"parent_tax_article": "Verginin hesablanması"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"article_name": "\tVergi Məcəlləsinin 102.1.22-3-ci maddəsində nəzərdə tutulmuş güzəşt tətbiq edilən faiz gəlirləri",
|
"article_name": "Vergi Məcəlləsinin 102.1.22-3-ci maddəsində nəzərdə tutulmuş güzəşt tətbiq edilən faiz gəlirləri",
|
||||||
"declaration": "Tax return withheld at source of payment",
|
"declaration": "Tax return withheld at source of payment",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Tax Article",
|
"doctype": "Tax Article",
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,367 @@
|
||||||
// Код для экспорта XML
|
|
||||||
frappe.ui.form.on('Land tax declaration', {
|
frappe.ui.form.on('Land tax declaration', {
|
||||||
refresh: function(frm) {
|
il: function(frm) {
|
||||||
frm.add_custom_button(__('Export XML'), function() {
|
if (frm.doc.il) {
|
||||||
frappe.call({
|
reload_assets_for_year(frm, frm.doc.il);
|
||||||
method: 'taxes_az.taxes_az.doctype.xml_mapping_tool.xml_mapping_tool.generate_xml',
|
}
|
||||||
args: {
|
}
|
||||||
mapping_tool: 'Land tax declaration', // Замените на имя вашего документа XML Mapping Tool
|
});
|
||||||
doctype: 'Land tax declaration', // Замените на имя DocType
|
|
||||||
docname: frm.docname
|
|
||||||
},
|
|
||||||
callback: function(r) {
|
|
||||||
if (r.message) {
|
|
||||||
// Создаем временный элемент для скачивания
|
|
||||||
var element = document.createElement('a');
|
|
||||||
element.setAttribute('href', 'data:text/xml;charset=utf-8,' + encodeURIComponent(r.message));
|
|
||||||
element.setAttribute('download', frm.docname + '.xml');
|
|
||||||
element.style.display = 'none';
|
|
||||||
document.body.appendChild(element);
|
|
||||||
element.click();
|
|
||||||
document.body.removeChild(element);
|
|
||||||
|
|
||||||
frappe.show_alert({
|
function reload_assets_for_year(frm, year) {
|
||||||
message: __('XML file generated and downloaded'),
|
// Clear existing tables
|
||||||
indicator: 'green'
|
frm.clear_table('əlavə_1');
|
||||||
|
frm.clear_table('əlavə_2');
|
||||||
|
frm.refresh_fields();
|
||||||
|
|
||||||
|
// Load assets for the specified year
|
||||||
|
Promise.all([
|
||||||
|
load_agricultural_assets_for_year(frm, 'əlavə_1', year),
|
||||||
|
load_industrial_assets_for_year(frm, 'əlavə_2', year)
|
||||||
|
]).then(() => {
|
||||||
|
frm.refresh_fields();
|
||||||
|
}).catch(() => {
|
||||||
|
// Silently handle any errors
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// AGRICULTURAL ASSETS (əlavə_1)
|
||||||
|
// ===============================
|
||||||
|
|
||||||
|
function load_agricultural_assets_for_year(frm, table_fieldname, year) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
frappe.call({
|
||||||
|
method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.get_assets_for_year',
|
||||||
|
args: {
|
||||||
|
asset_type: 'Kənd təsərrüfatı təyinatlı torpaq sahələri',
|
||||||
|
year: year
|
||||||
|
},
|
||||||
|
callback: function(response) {
|
||||||
|
if (response.message && response.message.length > 0) {
|
||||||
|
process_agricultural_assets_silent(frm, table_fieldname, response.message, resolve);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function process_agricultural_assets_silent(frm, table_fieldname, assets, resolve) {
|
||||||
|
let agricultural_purposes = {};
|
||||||
|
let processed_count = 0;
|
||||||
|
let unique_purposes = get_unique_purposes(assets);
|
||||||
|
|
||||||
|
if (unique_purposes.size > 0) {
|
||||||
|
unique_purposes.forEach(purpose_id => {
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get',
|
||||||
|
args: {
|
||||||
|
doctype: 'Agricultural Purpose Type',
|
||||||
|
name: purpose_id
|
||||||
|
},
|
||||||
|
callback: function(agri_response) {
|
||||||
|
if (agri_response.message) {
|
||||||
|
agricultural_purposes[purpose_id] = agri_response.message;
|
||||||
|
}
|
||||||
|
processed_count++;
|
||||||
|
|
||||||
|
if (processed_count === unique_purposes.size) {
|
||||||
|
group_and_create_agricultural_rows_silent(frm, table_fieldname, assets, agricultural_purposes, resolve);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
processed_count++;
|
||||||
|
if (processed_count === unique_purposes.size) {
|
||||||
|
group_and_create_agricultural_rows_silent(frm, table_fieldname, assets, agricultural_purposes, resolve);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, __('Actions'));
|
});
|
||||||
|
} else {
|
||||||
|
group_and_create_agricultural_rows_silent(frm, table_fieldname, assets, agricultural_purposes, resolve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
function get_unique_purposes(assets) {
|
||||||
|
let unique_purposes = new Set();
|
||||||
|
assets.forEach(asset => {
|
||||||
|
if (asset.agricultural_purpose) {
|
||||||
|
unique_purposes.add(asset.agricultural_purpose);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return unique_purposes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function group_and_create_agricultural_rows_silent(frm, table_fieldname, assets, agricultural_purposes, resolve) {
|
||||||
|
let grouped_assets = {};
|
||||||
|
|
||||||
|
assets.forEach(function(asset) {
|
||||||
|
let group_key = create_agricultural_group_key(asset, agricultural_purposes);
|
||||||
|
|
||||||
|
if (!grouped_assets[group_key]) {
|
||||||
|
grouped_assets[group_key] = {
|
||||||
|
asset: asset,
|
||||||
|
total_hectare: 0,
|
||||||
|
count: 0,
|
||||||
|
asset_names: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
grouped_assets[group_key].total_hectare += (asset.hectare || 0);
|
||||||
|
grouped_assets[group_key].count += 1;
|
||||||
|
grouped_assets[group_key].asset_names.push(asset.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
let total_groups = Object.keys(grouped_assets).length;
|
||||||
|
let completed_calculations = 0;
|
||||||
|
|
||||||
|
if (total_groups === 0) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(grouped_assets).forEach(function([group_key, group]) {
|
||||||
|
create_agricultural_row_with_calculation_silent(frm, table_fieldname, group.asset, agricultural_purposes, group.total_hectare, group, function() {
|
||||||
|
completed_calculations++;
|
||||||
|
|
||||||
|
if (completed_calculations === total_groups) {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_agricultural_group_key(asset, agricultural_purposes) {
|
||||||
|
let purpose_name = '';
|
||||||
|
if (asset.agricultural_purpose && agricultural_purposes[asset.agricultural_purpose]) {
|
||||||
|
purpose_name = agricultural_purposes[asset.agricultural_purpose].purpose_name || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
get_select_option_value(purpose_name),
|
||||||
|
asset.cadastral_district_code || '',
|
||||||
|
asset.cadastral_district_name || '',
|
||||||
|
asset.quality_groups || '',
|
||||||
|
asset.agricultural_land_purpose || ''
|
||||||
|
].join('|');
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_agricultural_row_with_calculation_silent(frm, table_fieldname, asset, agricultural_purposes, total_hectare, group_info, callback) {
|
||||||
|
let row = frm.add_child(table_fieldname);
|
||||||
|
|
||||||
|
fill_agricultural_row_fields(row, asset, agricultural_purposes, total_hectare, group_info);
|
||||||
|
|
||||||
|
calculate_agricultural_tax_for_row_silent(row, asset, total_hectare, group_info, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fill_agricultural_row_fields(row, asset, agricultural_purposes, total_hectare, group_info) {
|
||||||
|
if (asset.agricultural_purpose && agricultural_purposes[asset.agricultural_purpose]) {
|
||||||
|
let purpose_doc = agricultural_purposes[asset.agricultural_purpose];
|
||||||
|
if (purpose_doc.purpose_name) {
|
||||||
|
let mapped_value = get_select_option_value(purpose_doc.purpose_name);
|
||||||
|
row.bəyannaməsətrininkoduvəadı = mapped_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.cadastral_district_code) {
|
||||||
|
row.torpaqsahəsininyerləşdiyikadastrqiymətrayonununkodu = asset.cadastral_district_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.cadastral_district_name) {
|
||||||
|
row.torpaqsahəsininyerləşdiyikadastrqiymətrayonununadı = asset.cadastral_district_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.quality_groups) {
|
||||||
|
row.keyfiyyətqrupu = asset.quality_groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.agricultural_land_purpose) {
|
||||||
|
if (asset.agricultural_land_purpose === 'Əkin, dinc və çoxillik əkmələr') {
|
||||||
|
row.torpaqsahəsinintəyinatıəkindincçoxillikəkmələr = 1;
|
||||||
|
row.torpaqsahəsinintəyinatıbiçənəkörüşotlaqlar = 0;
|
||||||
|
} else if (asset.agricultural_land_purpose === 'Biçənək, örüş və otlaqlar') {
|
||||||
|
row.torpaqsahəsinintəyinatıəkindincçoxillikəkmələr = 0;
|
||||||
|
row.torpaqsahəsinintəyinatıbiçənəkörüşotlaqlar = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_hectare > 0) {
|
||||||
|
row.torpaqsahəsi6001kodlarüzrəkvmetrlə6002kodlarüzrəhektarlaümumi = total_hectare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculate_agricultural_tax_for_row_silent(row, asset, total_hectare, group_info, callback) {
|
||||||
|
if (!asset.cadastral_district_name || !asset.quality_groups || !asset.agricultural_land_purpose) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.calculate_agricultural_tax',
|
||||||
|
args: {
|
||||||
|
hectare: total_hectare,
|
||||||
|
cadastral_district_name: asset.cadastral_district_name,
|
||||||
|
quality_groups: asset.quality_groups,
|
||||||
|
agricultural_land_purpose: asset.agricultural_land_purpose
|
||||||
|
},
|
||||||
|
callback: function(response) {
|
||||||
|
if (response.message && response.message.tax_amount) {
|
||||||
|
row.vergiməbləğimanatla = response.message.tax_amount;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_select_option_value(purpose_name) {
|
||||||
|
if (purpose_name === 'Təyinatı üzrə istifadə edilməyən kənd təsərrüfatı torpaqları üzrə hesablanmış vergi məbləği') {
|
||||||
|
return '600.1 Təyinatı üzrə istifadə edilməyən kənd təsərrüfatı torpaqları üzrə hesablanmış vergi məbləği';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (purpose_name === 'Təyinatı üzrə istifadə edilən və ya irriqasiya, meliorasiya və digər aqrotexniki səbəblərdən təyinatı üzrə istifadə edilməsi mümkün olmayan kənd təsərrüfatı torpaqları üzrə verginin məbləği') {
|
||||||
|
return '600.2 Təyinatı üzrə istifadə edilən və ya irriqasiya, meliorasiya və digər aqrotexniki səbəblərdən təyinatı üzrə istifadə edilməsi mümkün olmayan kənd təsərrüfatı torpaqları üzrə verginin məbləği';
|
||||||
|
}
|
||||||
|
|
||||||
|
return purpose_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// INDUSTRIAL ASSETS (əlavə_2)
|
||||||
|
// ===============================
|
||||||
|
|
||||||
|
function load_industrial_assets_for_year(frm, table_fieldname, year) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
frappe.call({
|
||||||
|
method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.get_assets_for_year',
|
||||||
|
args: {
|
||||||
|
asset_type: 'Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xidməti və digər xüsusi təyinatlı torpaq sahələri',
|
||||||
|
year: year
|
||||||
|
},
|
||||||
|
callback: function(response) {
|
||||||
|
if (response.message && response.message.length > 0) {
|
||||||
|
group_and_create_industrial_rows_silent(frm, table_fieldname, response.message, resolve);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function group_and_create_industrial_rows_silent(frm, table_fieldname, assets, resolve) {
|
||||||
|
let grouped_assets = {};
|
||||||
|
|
||||||
|
assets.forEach(function(asset) {
|
||||||
|
let group_key = create_industrial_group_key(asset);
|
||||||
|
|
||||||
|
if (!grouped_assets[group_key]) {
|
||||||
|
grouped_assets[group_key] = {
|
||||||
|
asset: asset,
|
||||||
|
total_hectare: 0,
|
||||||
|
count: 0,
|
||||||
|
asset_names: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
grouped_assets[group_key].total_hectare += (asset.hectare || 0);
|
||||||
|
grouped_assets[group_key].count += 1;
|
||||||
|
grouped_assets[group_key].asset_names.push(asset.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
let total_groups = Object.keys(grouped_assets).length;
|
||||||
|
let completed_calculations = 0;
|
||||||
|
|
||||||
|
if (total_groups === 0) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.entries(grouped_assets).forEach(function([group_key, group]) {
|
||||||
|
create_industrial_row_with_calculation_silent(frm, table_fieldname, group.asset, group.total_hectare, group, function() {
|
||||||
|
completed_calculations++;
|
||||||
|
|
||||||
|
if (completed_calculations === total_groups) {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_industrial_group_key(asset) {
|
||||||
|
return [
|
||||||
|
asset.territorial_unit_name || '',
|
||||||
|
asset.territorial_unit_code || '',
|
||||||
|
asset.industrial_land_purpose || '',
|
||||||
|
asset.mining_note ? 'mining' : 'no_mining'
|
||||||
|
].join('|');
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_industrial_row_with_calculation_silent(frm, table_fieldname, asset, total_hectare, group_info, callback) {
|
||||||
|
let row = frm.add_child(table_fieldname);
|
||||||
|
|
||||||
|
fill_industrial_row_fields(row, asset, total_hectare, group_info);
|
||||||
|
|
||||||
|
calculate_industrial_tax_for_row_silent(row, asset, total_hectare, group_info, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fill_industrial_row_fields(row, asset, total_hectare, group_info) {
|
||||||
|
if (asset.territorial_unit_code) {
|
||||||
|
row.torpaqsahəsininyerləşdiyiəraziməntəqəsininkodu = parseFloat(asset.territorial_unit_code) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.territorial_unit_name) {
|
||||||
|
row.torpaqsahəsininyerləşdiyiəraziməntəqəsininadı = asset.territorial_unit_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.industrial_land_purpose) {
|
||||||
|
if (asset.industrial_land_purpose === 'Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xid-ti və dig. xüs. təy-tlı sahələr') {
|
||||||
|
row.torpaqsahəsinintəyinatısənayətikinti = 1;
|
||||||
|
row.torpaqsahəsinintəyinatıyaşayışfondları = 0;
|
||||||
|
} else if (asset.industrial_land_purpose === 'Yaşayış fondları, həyətyanı və bağsahələri üzrə sahələr') {
|
||||||
|
row.torpaqsahəsinintəyinatısənayətikinti = 0;
|
||||||
|
row.torpaqsahəsinintəyinatıyaşayışfondları = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset.mining_note !== undefined) {
|
||||||
|
row.faydalıqazıntıçıxarılmasıbarədəqeyd = asset.mining_note ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (total_hectare > 0) {
|
||||||
|
row.torpaqsahəsikvmetrləümumisahə = total_hectare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculate_industrial_tax_for_row_silent(row, asset, total_hectare, group_info, callback) {
|
||||||
|
if (!asset.territorial_unit_name || !asset.industrial_land_purpose) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: 'taxes_az.taxes_az.doctype.land_tax_declaration.land_tax_declaration.calculate_industrial_tax',
|
||||||
|
args: {
|
||||||
|
hectare: total_hectare,
|
||||||
|
territorial_unit_name: asset.territorial_unit_name,
|
||||||
|
industrial_land_purpose: asset.industrial_land_purpose
|
||||||
|
},
|
||||||
|
callback: function(response) {
|
||||||
|
if (response.message && response.message.tax_amount) {
|
||||||
|
row.vergiməbləğimanatla = response.message.tax_amount;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -370,7 +370,7 @@
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-09-02 17:05:55.022813",
|
"modified": "2025-09-16 11:29:30.443609",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Taxes Az",
|
"module": "Taxes Az",
|
||||||
"name": "Land tax declaration",
|
"name": "Land tax declaration",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,333 @@
|
||||||
# Copyright (c) 2025, Jey Soft and contributors
|
import frappe
|
||||||
# For license information, please see license.txt
|
import json
|
||||||
|
import os
|
||||||
# import frappe
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
class Landtaxdeclaration(Document):
|
class Landtaxdeclaration(Document):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_doctype_fields_info():
|
||||||
|
"""Gets information about fields of əlavə_1 table and Asset"""
|
||||||
|
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get metadata for əlavə_1 table
|
||||||
|
elave1_meta = frappe.get_meta('Land tax declaration Elave 1')
|
||||||
|
result['elave1_fields'] = []
|
||||||
|
|
||||||
|
for field in elave1_meta.fields:
|
||||||
|
field_info = {
|
||||||
|
'fieldname': field.fieldname,
|
||||||
|
'label': field.label,
|
||||||
|
'fieldtype': field.fieldtype,
|
||||||
|
'options': field.options or '',
|
||||||
|
'reqd': field.reqd,
|
||||||
|
'read_only': field.read_only
|
||||||
|
}
|
||||||
|
result['elave1_fields'].append(field_info)
|
||||||
|
|
||||||
|
# Get metadata for əlavə_2 table
|
||||||
|
elave2_meta = frappe.get_meta('Land tax declaration Elave 2')
|
||||||
|
result['elave2_fields'] = []
|
||||||
|
|
||||||
|
for field in elave2_meta.fields:
|
||||||
|
field_info = {
|
||||||
|
'fieldname': field.fieldname,
|
||||||
|
'label': field.label,
|
||||||
|
'fieldtype': field.fieldtype,
|
||||||
|
'options': field.options or '',
|
||||||
|
'reqd': field.reqd,
|
||||||
|
'read_only': field.read_only
|
||||||
|
}
|
||||||
|
result['elave2_fields'].append(field_info)
|
||||||
|
|
||||||
|
# Get metadata for Asset
|
||||||
|
asset_meta = frappe.get_meta('Asset')
|
||||||
|
result['asset_fields'] = []
|
||||||
|
|
||||||
|
for field in asset_meta.fields:
|
||||||
|
field_info = {
|
||||||
|
'fieldname': field.fieldname,
|
||||||
|
'label': field.label,
|
||||||
|
'fieldtype': field.fieldtype,
|
||||||
|
'options': field.options or '',
|
||||||
|
'reqd': field.reqd,
|
||||||
|
'depends_on': field.depends_on or ''
|
||||||
|
}
|
||||||
|
result['asset_fields'].append(field_info)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
frappe.log_error(f"Error in get_doctype_fields_info: {str(e)}")
|
||||||
|
return {'error': str(e)}
|
||||||
|
|
||||||
|
# ===============================
|
||||||
|
# AGRICULTURAL LAND CALCULATIONS
|
||||||
|
# ===============================
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def calculate_agricultural_tax(hectare, cadastral_district_name, quality_groups, agricultural_land_purpose):
|
||||||
|
"""
|
||||||
|
Calculates tax for agricultural land
|
||||||
|
Formula: hectare × score × markup
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Input validation
|
||||||
|
if not hectare or not cadastral_district_name or not quality_groups or not agricultural_land_purpose:
|
||||||
|
frappe.throw("Not all fields are filled for calculation")
|
||||||
|
|
||||||
|
# Get score from JSON file
|
||||||
|
score = get_cadastral_score(cadastral_district_name, quality_groups)
|
||||||
|
|
||||||
|
# Determine markup
|
||||||
|
markup = get_markup_coefficient(agricultural_land_purpose)
|
||||||
|
|
||||||
|
# Calculate using formula
|
||||||
|
result = float(hectare) * score * markup
|
||||||
|
|
||||||
|
return {
|
||||||
|
'tax_amount': result,
|
||||||
|
'calculation_details': {
|
||||||
|
'hectare': float(hectare),
|
||||||
|
'score': score,
|
||||||
|
'markup': markup,
|
||||||
|
'formula': f"{hectare} × {score} × {markup} = {result}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(f"Error during calculation: {str(e)}")
|
||||||
|
|
||||||
|
def get_cadastral_score(cadastral_district_name, quality_group):
|
||||||
|
"""
|
||||||
|
Extracts score from JSON file based on cadastral district name and quality group
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Path to JSON file
|
||||||
|
json_file_path = frappe.get_app_path('taxes_az', 'data', 'cadastral_points_data.json')
|
||||||
|
|
||||||
|
# Read JSON file
|
||||||
|
with open(json_file_path, 'r', encoding='utf-8') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
# Find corresponding region
|
||||||
|
for region in data.get('cadastral_regions', []):
|
||||||
|
if region.get('region_name') == cadastral_district_name:
|
||||||
|
# Get score for specified quality group
|
||||||
|
quality_groups = region.get('quality_groups', {})
|
||||||
|
score = quality_groups.get(quality_group)
|
||||||
|
|
||||||
|
# If score is null or not found, return 0
|
||||||
|
return score if score is not None else 0
|
||||||
|
|
||||||
|
# If region not found
|
||||||
|
frappe.throw(f"Cadastral district '{cadastral_district_name}' not found in database")
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
frappe.throw("Cadastral data file not found. Contact system administrator")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
frappe.throw("Error reading cadastral data file")
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(f"Error getting cadastral score: {str(e)}")
|
||||||
|
|
||||||
|
def get_markup_coefficient(agricultural_land_purpose):
|
||||||
|
"""
|
||||||
|
Determines markup coefficient based on land use purpose
|
||||||
|
"""
|
||||||
|
markup_map = {
|
||||||
|
"Əkin, dinc və çoxillik əkmələr": 0.06,
|
||||||
|
"Biçənək, örüş və otlaqlar": 0.006 # 0.06 / 10
|
||||||
|
}
|
||||||
|
|
||||||
|
coefficient = markup_map.get(agricultural_land_purpose)
|
||||||
|
|
||||||
|
if coefficient is None:
|
||||||
|
frappe.throw(f"Unknown land purpose type: {agricultural_land_purpose}")
|
||||||
|
|
||||||
|
return coefficient
|
||||||
|
|
||||||
|
# ===============================
|
||||||
|
# INDUSTRIAL/COMMERCIAL LAND CALCULATIONS
|
||||||
|
# ===============================
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def calculate_industrial_tax(hectare, territorial_unit_name, industrial_land_purpose):
|
||||||
|
"""
|
||||||
|
Calculates tax for industrial land
|
||||||
|
Formula: (area_in_sqm ÷ 100) × score (progressive system)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Input validation
|
||||||
|
if not hectare or not territorial_unit_name or not industrial_land_purpose:
|
||||||
|
frappe.throw("Not all fields are filled for calculation")
|
||||||
|
|
||||||
|
# Use value as is - this is square meters
|
||||||
|
area_sqm = float(hectare)
|
||||||
|
|
||||||
|
# Get scores from JSON file
|
||||||
|
score_data = get_industrial_land_scores(territorial_unit_name, industrial_land_purpose)
|
||||||
|
|
||||||
|
# Calculate using progressive formula
|
||||||
|
calculation_result = calculate_industrial_land_formula(area_sqm, score_data)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'tax_amount': calculation_result['total'],
|
||||||
|
'calculation_details': calculation_result
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(f"Error during calculation: {str(e)}")
|
||||||
|
|
||||||
|
def get_industrial_land_scores(territorial_unit_name, industrial_land_purpose):
|
||||||
|
"""
|
||||||
|
Extracts scores from JSON file for industrial land
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Path to JSON file
|
||||||
|
json_file_path = frappe.get_app_path('taxes_az', 'data', 'industrial_land_data.json')
|
||||||
|
|
||||||
|
# Read JSON file
|
||||||
|
with open(json_file_path, 'r', encoding='utf-8') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
# Find corresponding region
|
||||||
|
for region in data.get('industrial_land_regions', []):
|
||||||
|
if region.get('settlement_name') == territorial_unit_name:
|
||||||
|
# Get scores for specified land purpose
|
||||||
|
land_purpose_rates = region.get('land_purpose_rates', {})
|
||||||
|
purpose_rates = land_purpose_rates.get(industrial_land_purpose)
|
||||||
|
|
||||||
|
if purpose_rates:
|
||||||
|
return {
|
||||||
|
'up_to_10000': purpose_rates.get('up_to_10000_sqm', 0),
|
||||||
|
'above_10000': purpose_rates.get('above_10000_sqm', 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
# If region or purpose not found
|
||||||
|
frappe.throw(f"Data not found for territory '{territorial_unit_name}' and purpose '{industrial_land_purpose}'")
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
frappe.throw("Industrial land data file not found. Contact system administrator")
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
frappe.throw("Error reading industrial land data file")
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(f"Error getting industrial land scores: {str(e)}")
|
||||||
|
|
||||||
|
def calculate_industrial_land_formula(area_sqm, score_data):
|
||||||
|
"""
|
||||||
|
Calculates cost using progressive formula for industrial land
|
||||||
|
"""
|
||||||
|
up_to_10000_score = score_data['up_to_10000']
|
||||||
|
above_10000_score = score_data['above_10000']
|
||||||
|
|
||||||
|
calculation_parts = []
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
if area_sqm <= 10000:
|
||||||
|
# All area up to 10000 sqm
|
||||||
|
part_result = (area_sqm / 100) * up_to_10000_score
|
||||||
|
total = part_result
|
||||||
|
|
||||||
|
calculation_parts.append({
|
||||||
|
'area': area_sqm,
|
||||||
|
'score': up_to_10000_score,
|
||||||
|
'formula': f"{area_sqm} ÷ 100 × {up_to_10000_score} = {part_result}",
|
||||||
|
'result': part_result
|
||||||
|
})
|
||||||
|
|
||||||
|
formula_text = f"{area_sqm} ÷ 100 × {up_to_10000_score} = {total}"
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Progressive system: up to 10000 sqm + above 10000 sqm
|
||||||
|
|
||||||
|
# First 10000 sqm
|
||||||
|
part1_result = (10000 / 100) * up_to_10000_score
|
||||||
|
calculation_parts.append({
|
||||||
|
'area': 10000,
|
||||||
|
'score': up_to_10000_score,
|
||||||
|
'formula': f"10000 ÷ 100 × {up_to_10000_score} = {part1_result}",
|
||||||
|
'result': part1_result
|
||||||
|
})
|
||||||
|
|
||||||
|
# Remaining area above 10000 sqm
|
||||||
|
remaining_area = area_sqm - 10000
|
||||||
|
part2_result = (remaining_area / 100) * above_10000_score
|
||||||
|
calculation_parts.append({
|
||||||
|
'area': remaining_area,
|
||||||
|
'score': above_10000_score,
|
||||||
|
'formula': f"{remaining_area} ÷ 100 × {above_10000_score} = {part2_result}",
|
||||||
|
'result': part2_result
|
||||||
|
})
|
||||||
|
|
||||||
|
total = part1_result + part2_result
|
||||||
|
formula_text = f"(10000 ÷ 100 × {up_to_10000_score}) + ({remaining_area} ÷ 100 × {above_10000_score}) = {part1_result} + {part2_result} = {total}"
|
||||||
|
|
||||||
|
return {
|
||||||
|
'total': total,
|
||||||
|
'area_sqm': area_sqm,
|
||||||
|
'formula': formula_text,
|
||||||
|
'calculation_parts': calculation_parts,
|
||||||
|
'scores_used': score_data
|
||||||
|
}
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_assets_for_year(asset_type, year):
|
||||||
|
"""
|
||||||
|
Gets assets filtered by type and purchase year
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Convert year to int for comparison
|
||||||
|
target_year = int(year)
|
||||||
|
|
||||||
|
# Build filters
|
||||||
|
filters = {
|
||||||
|
'docstatus': 1,
|
||||||
|
'custom_asset_type': asset_type
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get appropriate fields based on asset type
|
||||||
|
if asset_type == 'Kənd təsərrüfatı təyinatlı torpaq sahələri':
|
||||||
|
fields = [
|
||||||
|
'name',
|
||||||
|
'asset_name',
|
||||||
|
'agricultural_purpose',
|
||||||
|
'cadastral_district_name',
|
||||||
|
'cadastral_district_code',
|
||||||
|
'quality_groups',
|
||||||
|
'agricultural_land_purpose',
|
||||||
|
'hectare',
|
||||||
|
'purchase_date'
|
||||||
|
]
|
||||||
|
else: # Industrial assets
|
||||||
|
fields = [
|
||||||
|
'name',
|
||||||
|
'asset_name',
|
||||||
|
'territorial_unit_name',
|
||||||
|
'territorial_unit_code',
|
||||||
|
'industrial_land_purpose',
|
||||||
|
'mining_note',
|
||||||
|
'hectare',
|
||||||
|
'purchase_date'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Get all assets of the specified type
|
||||||
|
assets = frappe.get_list('Asset', filters=filters, fields=fields)
|
||||||
|
|
||||||
|
# Filter by purchase_date year
|
||||||
|
filtered_assets = []
|
||||||
|
for asset in assets:
|
||||||
|
if asset.get('purchase_date'):
|
||||||
|
purchase_year = asset['purchase_date'].year
|
||||||
|
if purchase_year == target_year:
|
||||||
|
filtered_assets.append(asset)
|
||||||
|
# If no purchase_date, we can decide whether to include or exclude
|
||||||
|
# For now, excluding assets without purchase_date
|
||||||
|
|
||||||
|
return filtered_assets
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
frappe.log_error(f"Error in get_assets_for_year: {str(e)}")
|
||||||
|
return []
|
||||||
|
|
@ -28,17 +28,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "torpaqsah\u0259sininyerl\u0259\u015fdiyikadastrqiym\u0259trayonununad\u0131",
|
"fieldname": "torpaqsah\u0259sininyerl\u0259\u015fdiyikadastrqiym\u0259trayonununad\u0131",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Torpaq sah\u0259sinin yerl\u0259\u015fdiyi kadastr qiym\u0259t rayonunun ad\u0131",
|
"label": "Torpaq sah\u0259sinin yerl\u0259\u015fdiyi kadastr qiym\u0259t rayonunun ad\u0131",
|
||||||
"options": "\u0410b\u015feron\u2014Qobustan (\u0410b\u015feron rayonu, Hac\u0131qabul rayonunun N\u0259vahi-\u0410tbulaq massivi, Siy\u0259z\u0259n v\u0259 X\u0131z\u0131 rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131, habel\u0259 Bak\u0131 v\u0259 Sumqay\u0131t \u015f\u0259h\u0259rl\u0259rinin m\u00f6vcud h\u00fcdudundan k\u0259narda olan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 t\u0259`yinatl\u0131 torpaqlar\u0131)\n\u015eabran\u2014Xa\u00e7maz (Xa\u00e7maz rayonu, D\u0259v\u0259\u00e7i, Quba, Qusar v\u0259 Siy\u0259z\u0259n rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131)\nQan\u0131x\u2014T\u00fcryan\u00e7ay (Balak\u0259n, Qax, Zaqatala, \u015e\u0259ki, O\u011fuz v\u0259 Q\u0259b\u0259l\u0259 rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131)\n\u015e\u0259ki-Zaqatala (Balak\u0259n, Qax, Zaqatala, \u015e\u0259ki, O\u011fuz v\u0259 Q\u0259b\u0259l\u0259 rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\nQusar\u2014Qonaqk\u0259nd (Qusar, Quba, D\u0259v\u0259\u00e7i, Siy\u0259z\u0259n v\u0259 X\u0131z\u0131 rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\nX\u0131nal\u0131q\u2014Xaltan (Qusar v\u0259 Quba rayonlar\u0131n\u0131n orta v\u0259 y\u00fcks\u0259k da\u011f torpaqlar\u0131)\nDa\u011f\u2014\u015eirvan (\u015eamax\u0131, \u0130smay\u0131ll\u0131 rayonlar\u0131, \u0410\u011fsu v\u0259 G\u00f6y\u00e7ay rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\nQobustan\u2014Xilmilli (Qobustan rayonunun da\u011f torpaqlar\u0131)\nG\u0259nc\u0259\u2014Qazax (Samux rayonu, Goranboy, G\u00f6yg\u00f6l, Tovuz, \u0410\u011fstafa, \u015e\u0259mkir v\u0259 Qazax rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131, habel\u0259 G\u0259nc\u0259 v\u0259 Naftalan \u015f\u0259h\u0259rl\u0259rinin m\u00f6vcud h\u00fcdudundan k\u0259narda olan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 t\u0259`yinatl\u0131 torpaqlar\u0131)\nMil\u2014Qaraba\u011f (B\u0259rd\u0259, \u0410\u011fc\u0259b\u0259di, Beyl\u0259qan, T\u0259rt\u0259r rayonlar\u0131, \u0410\u011fdam, ke\u00e7mi\u015f \u0410\u011fd\u0259r\u0259 rayonunun \u0259razisi v\u0259 Xocav\u0259ndin d\u00fcz\u0259n torpaqlar\u0131)\n\u0410razboyu (F\u00fczuli, Z\u0259ngilan v\u0259 C\u0259bray\u0131l rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131)\nDa\u015fk\u0259s\u0259n\u2014G\u0259d\u0259b\u0259y (G\u0259d\u0259b\u0259y, Da\u015fk\u0259s\u0259n rayonlar\u0131, Goranboy, Xanlar, \u015e\u0259mkir, Tovuz, \u0410\u011fstafa v\u0259 Qazax rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\nLa\u00e7\u0131n\u2014Qubadl\u0131 (K\u0259lb\u0259c\u0259r, La\u00e7\u0131n, Qubadl\u0131 rayonlar\u0131 v\u0259 Z\u0259ngilan rayonunun da\u011f torpaqlar\u0131)\nDa\u011f\u2014Qaraba\u011f (\u015eu\u015fa, Xocal\u0131 rayonlar\u0131, Xocav\u0259nd, ke\u00e7mi\u015f \u0410\u011fd\u0259r\u0259 rayonunun \u0259razisi, habel\u0259 \u0410\u011fdam, F\u00fczuli, C\u0259bray\u0131l rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\nMu\u011fan-Salyan (Salyan, Saatl\u0131, Sabirabad, \u0130mi\u015fli, Neft\u00e7ala v\u0259 Bil\u0259suvar rayonlar\u0131, Hac\u0131qabulun K\u00fcrq\u0131ra\u011f\u0131 d\u00fcz\u0259n hiss\u0259si, habel\u0259 \u015eirvan \u015f\u0259h\u0259rinin m\u00f6vcud h\u00fcdudundan k\u0259narda olan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 t\u0259`yinatl\u0131 torpaqlar\u0131)\n\u0410ran\u2014\u015eirvan (K\u00fcrd\u0259mir, Z\u0259rdab, Ucar, Yevlax, \u0410\u011fda\u015f rayonlar\u0131, \u0410\u011fsu, G\u00f6y\u00e7ay rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131 v\u0259 Ming\u0259\u00e7evir \u015f\u0259h\u0259rinin m\u00f6vcud h\u00fcdudundan k\u0259narda olan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 t\u0259`yinatl\u0131 torpaqlar\u0131)\nL\u0259nk\u0259ran\u2014\u0410stara (L\u0259nk\u0259ran, Masall\u0131 v\u0259 \u0410stara rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131)\nC\u0259lilabad (C\u0259lilabad rayonunun d\u00fcz\u0259n torpaqlar\u0131)\n\u00dc\u00e7t\u0259p\u0259\u2014T\u0259z\u0259k\u0259nd (C\u0259lilabad rayonunun da\u011f torpaqlar\u0131)\nLerik\u2014 Yard\u0131ml\u0131 (Lerik, Yard\u0131ml\u0131 rayonlar\u0131, Masall\u0131, L\u0259nk\u0259ran v\u0259 \u0410stara rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)\n\u015e\u0259rur\u2014Ordubad (\u015e\u0259rur, S\u0259d\u0259r\u0259k, Bab\u0259k, Ordubad v\u0259 Culfa rayonlar\u0131n\u0131n d\u00fcz\u0259n torpaqlar\u0131)\n\u015eahbuz\u2014Paraqa\u00e7ay (\u015eahbuz rayonu, \u015e\u0259rur, S\u0259d\u0259r\u0259k, Bab\u0259k, Ordubad, Culfa rayonlar\u0131n\u0131n da\u011f torpaqlar\u0131)"
|
"options": "Cadastral Valuation District"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "keyfiyy\u0259tqrupu",
|
"fieldname": "keyfiyy\u0259tqrupu",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Keyfiyy\u0259t qrupu",
|
"label": "Keyfiyy\u0259t qrupu",
|
||||||
"options": "I\nII\nIII\nIV\nV"
|
"options": "\nI\nII\nIII\nIV\nV"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "B\u0259yannam\u0259 s\u0259trinin kodu v\u0259 ad\u0131",
|
"label": "B\u0259yannam\u0259 s\u0259trinin kodu v\u0259 ad\u0131",
|
||||||
"options": "600.1 T\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edilm\u0259y\u0259n k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 torpaqlar\u0131 \u00fczr\u0259 hesablanm\u0131\u015f vergi m\u0259bl\u0259\u011fi\n600.2 T\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edil\u0259n v\u0259 ya irriqasiya, meliorasiya v\u0259 dig\u0259r aqrotexniki s\u0259b\u0259bl\u0259rd\u0259n t\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edilm\u0259si m\u00fcmk\u00fcn olmayan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 torpaqlar\u0131 \u00fczr\u0259 verginin m\u0259bl\u0259\u011fi"
|
"options": "\n600.1 T\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edilm\u0259y\u0259n k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 torpaqlar\u0131 \u00fczr\u0259 hesablanm\u0131\u015f vergi m\u0259bl\u0259\u011fi\n600.2 T\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edil\u0259n v\u0259 ya irriqasiya, meliorasiya v\u0259 dig\u0259r aqrotexniki s\u0259b\u0259bl\u0259rd\u0259n t\u0259yinat\u0131 \u00fczr\u0259 istifad\u0259 edilm\u0259si m\u00fcmk\u00fcn olmayan k\u0259nd t\u0259s\u0259rr\u00fcfat\u0131 torpaqlar\u0131 \u00fczr\u0259 verginin m\u0259bl\u0259\u011fi"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "torpaqsah\u0259sininoldu\u011fuaylar\u0131nsay\u0131",
|
"fieldname": "torpaqsah\u0259sininoldu\u011fuaylar\u0131nsay\u0131",
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-09-02 16:46:09.956144",
|
"modified": "2025-09-15 18:59:22.874265",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Taxes Az",
|
"module": "Taxes Az",
|
||||||
"name": "Land tax declaration Elave 1",
|
"name": "Land tax declaration Elave 1",
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Torpaq sah\u0259sinin yerl\u0259\u015fdiyi \u0259razi m\u0259nt\u0259q\u0259sinin ad\u0131",
|
"label": "Torpaq sah\u0259sinin yerl\u0259\u015fdiyi \u0259razi m\u0259nt\u0259q\u0259sinin ad\u0131",
|
||||||
"options": "Bak\u0131\nG\u0259nc\u0259, Sumqay\u0131t,X\u0131rdalan,Ab\u015feron\nDig\u0259r \u015f\u0259h\u0259rl\u0259r (rayon tabeliyind\u0259 olan \u015f\u0259h\u0259rl\u0259r istisna olmaqla), Rayon m\u0259rk\u0259zl\u0259ri\nRayon tabe\u00e7iliyind\u0259 olan \u015f\u0259h\u0259rl\u0259rd\u0259, q\u0259s\u0259b\u0259l\u0259rd\u0259 v\u0259 k\u0259ndl\u0259rd\u0259 (Bak\u0131 v\u0259 Sumqay\u0131t \u015f\u0259h\u0259rl\u0259rinin q\u0259s\u0259b\u0259 v\u0259 k\u0259ndl\u0259ri istisna olmaqla)"
|
"options": "\nBak\u0131\nG\u0259nc\u0259, Sumqay\u0131t,X\u0131rdalan,Ab\u015feron\nDig\u0259r \u015f\u0259h\u0259rl\u0259r (rayon tabeliyind\u0259 olan \u015f\u0259h\u0259rl\u0259r istisna olmaqla), Rayon m\u0259rk\u0259zl\u0259ri\nRayon tabe\u00e7iliyind\u0259 olan \u015f\u0259h\u0259rl\u0259rd\u0259, q\u0259s\u0259b\u0259l\u0259rd\u0259 v\u0259 k\u0259ndl\u0259rd\u0259 (Bak\u0131 v\u0259 Sumqay\u0131t \u015f\u0259h\u0259rl\u0259rinin q\u0259s\u0259b\u0259 v\u0259 k\u0259ndl\u0259ri istisna olmaqla)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-09-02 16:36:58.193908",
|
"modified": "2025-09-15 15:29:16.279740",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Taxes Az",
|
"module": "Taxes Az",
|
||||||
"name": "Land tax declaration Elave 2",
|
"name": "Land tax declaration Elave 2",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,412 @@
|
||||||
|
// Copyright (c) 2024, Your Company and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.query_reports["Tax Exempt Assets Establishment Year Report"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatter": function (value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
// Подсветка колонок с остатками и страховкой
|
||||||
|
if (column.fieldname && column.fieldname.includes("value_")) {
|
||||||
|
if (value && parseFloat(value) > 0) {
|
||||||
|
// Разные цвета для разных типов колонок - специальные для tax exempt
|
||||||
|
let color = "#28a745"; // зеленый по умолчанию
|
||||||
|
|
||||||
|
if (column.fieldname.includes("_value_from")) {
|
||||||
|
color = "#6610f2"; // фиолетовый для начальных остатков
|
||||||
|
} else if (column.fieldname.includes("_value_to")) {
|
||||||
|
color = "#198754"; // темно-зеленый для конечных остатков
|
||||||
|
} else if (column.fieldname.includes("_insured")) {
|
||||||
|
color = "#d63384"; // розовый для страховки
|
||||||
|
}
|
||||||
|
|
||||||
|
value = `<span style="color: ${color}; font-weight: bold; background-color: ${color}20; padding: 3px 8px; border-radius: 4px; border-left: 3px solid ${color};">${value}</span>`;
|
||||||
|
} else if (value == 0 || !value) {
|
||||||
|
value = `<span style="color: #ccc;">0.00</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Asset колонки - специальная для tax exempt establishment year
|
||||||
|
if (column.fieldname == "asset" && value) {
|
||||||
|
value = `<span style="color: #6610f2; font-weight: bold; background-color: #6610f215; padding: 2px 6px; border-radius: 3px;">⚖️ ${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Date колонки
|
||||||
|
if (column.fieldname == "purchase_date" && value) {
|
||||||
|
value = `<span style="color: #d63384; font-weight: 600;">📅 ${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
"onload": function(report) {
|
||||||
|
// Добавляем кастомные кнопки
|
||||||
|
report.page.add_inner_button(__("Export Tax Exempt Summary"), function() {
|
||||||
|
export_tax_exempt_establishment_year_summary(report);
|
||||||
|
});
|
||||||
|
|
||||||
|
report.page.add_inner_button(__("Show Tax Articles"), function() {
|
||||||
|
show_tax_articles_info();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем информационное сообщение
|
||||||
|
report.page.add_inner_button(__("About This Report"), function() {
|
||||||
|
show_tax_exempt_report_info(report);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"after_datatable_render": function(datatable_obj) {
|
||||||
|
// Добавляем итоговую статистику
|
||||||
|
setTimeout(() => {
|
||||||
|
add_tax_exempt_establishment_year_statistics(datatable_obj);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Функция показа информации об отчете
|
||||||
|
function show_tax_exempt_report_info(report) {
|
||||||
|
let company = report.filters.find(f => f.fieldname === 'company').value;
|
||||||
|
|
||||||
|
if (company) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get_value',
|
||||||
|
args: {
|
||||||
|
doctype: 'Company',
|
||||||
|
fieldname: 'date_of_establishment',
|
||||||
|
filters: {name: company}
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
let establishment_date = r.message ? r.message.date_of_establishment : 'N/A';
|
||||||
|
let establishment_year = establishment_date !== 'N/A' ? new Date(establishment_date).getFullYear() : 'N/A';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Tax Exempt Establishment Year Report Information"),
|
||||||
|
message: `
|
||||||
|
<div style="padding: 15px;">
|
||||||
|
<h4 style="color: #6610f2; margin-bottom: 15px;">⚖️ Vergidən azad olunan əsas vəsaitlər - Təsis ili</h4>
|
||||||
|
<hr>
|
||||||
|
<p><strong>Şirkət:</strong> ${company}</p>
|
||||||
|
<p><strong>Təsis tarixi:</strong> ${establishment_date}</p>
|
||||||
|
<p><strong>Təsis ili:</strong> ${establishment_year}</p>
|
||||||
|
<hr>
|
||||||
|
<p style="color: #6c757d; margin-bottom: 10px;">
|
||||||
|
<strong>Bu hesabat göstərir:</strong><br>
|
||||||
|
• Yalnız şirkətin təsis ilində alınmış aktivləri<br>
|
||||||
|
• Vergidən azad olunan əsas vəsaitlər tipində olanları<br>
|
||||||
|
• Tax exempt maddələr üzrə qalıqlar və sığorta dəyəri<br>
|
||||||
|
• Vergi Məcəlləsinin 199, 227 maddələri və beynəlxalq müqavilələr
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
frappe.msgprint(__('Please select a company first'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция экспорта сводки по налоговым статьям года создания
|
||||||
|
function export_tax_exempt_establishment_year_summary(report) {
|
||||||
|
let data = report.data;
|
||||||
|
let summary = calculate_tax_totals(data);
|
||||||
|
|
||||||
|
// Создаем CSV с итогами по налоговым статьям года создания
|
||||||
|
let csv_content = "Tax Article (Establishment Year),Assets Count,Total Value From,Total Value To,Total Insured Value\n";
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
csv_content += `"${item.article}",${item.assets_count},${item.total_value_from},${item.total_value_to},${item.total_insured}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
csv_content += `\n"TOTAL (TAX EXEMPT ESTABLISHMENT YEAR)",${totals.total_assets},${totals.total_value_from},${totals.total_value_to},${totals.total_insured}\n`;
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'tax_exempt_assets_establishment_year_' + frappe.datetime.get_today() + '.csv';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
frappe.show_alert({message: __("Tax exempt establishment year summary exported successfully"), indicator: "green"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция расчета итогов по налоговым статьям
|
||||||
|
function calculate_tax_totals(data) {
|
||||||
|
let tax_articles = get_tax_articles_list();
|
||||||
|
let summary = [];
|
||||||
|
|
||||||
|
tax_articles.forEach(article => {
|
||||||
|
let article_key = get_field_key_js(article.full_name);
|
||||||
|
let assets_count = 0;
|
||||||
|
let total_value_from = 0;
|
||||||
|
let total_value_to = 0;
|
||||||
|
let total_insured = 0;
|
||||||
|
|
||||||
|
data.forEach(row => {
|
||||||
|
let value_from = row[`${article_key}_value_from`] || 0;
|
||||||
|
let value_to = row[`${article_key}_value_to`] || 0;
|
||||||
|
let insured = row[`${article_key}_insured`] || 0;
|
||||||
|
|
||||||
|
if (value_from > 0 || value_to > 0 || insured > 0) {
|
||||||
|
assets_count++;
|
||||||
|
total_value_from += value_from;
|
||||||
|
total_value_to += value_to;
|
||||||
|
total_insured += insured;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assets_count > 0) {
|
||||||
|
summary.push({
|
||||||
|
article: article.short_name,
|
||||||
|
assets_count: assets_count,
|
||||||
|
total_value_from: total_value_from,
|
||||||
|
total_value_to: total_value_to,
|
||||||
|
total_insured: total_insured
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция показа информации о налоговых статьях
|
||||||
|
function show_tax_articles_info() {
|
||||||
|
let tax_articles = get_tax_articles_list();
|
||||||
|
let info_html = '<div class="tax-articles-info">';
|
||||||
|
info_html += '<h4>⚖️ Təsis ilində alınmış vergidən azad olunan aktivlərin vergi maddələri:</h4>';
|
||||||
|
info_html += '<div class="row">';
|
||||||
|
|
||||||
|
tax_articles.forEach((article, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
info_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
info_html += '<div class="col-md-6" style="margin-bottom: 8px;">';
|
||||||
|
info_html += `<strong>${article.short_name}:</strong><br>`;
|
||||||
|
info_html += `<small style="color: #6c757d;">${article.full_name}</small>`;
|
||||||
|
info_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
info_html += '</div></div>';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Tax Articles Information"),
|
||||||
|
message: info_html,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция добавления статистики под таблицу
|
||||||
|
function add_tax_exempt_establishment_year_statistics(datatable_obj) {
|
||||||
|
if (datatable_obj && datatable_obj.data) {
|
||||||
|
let summary = calculate_tax_totals(datatable_obj.data);
|
||||||
|
|
||||||
|
let stats_html = '<div class="tax-exempt-establishment-year-statistics" style="margin-top: 20px; padding: 20px; background: linear-gradient(135deg, #f8f5ff 0%, #fff 100%); border-radius: 8px; border: 2px solid #6610f2; box-shadow: 0 2px 8px rgba(102,16,242,0.1);">';
|
||||||
|
stats_html += '<h4 style="margin-bottom: 15px; color: #6610f2; display: flex; align-items: center;"><span style="margin-right: 8px;">⚖️</span> Təsis ili üzrə vergidən azad olunan əsas vəsaitlər:</h4>';
|
||||||
|
|
||||||
|
// Группируем по типам статей
|
||||||
|
let grouped_summary = group_summary_by_tax_article_type(summary);
|
||||||
|
|
||||||
|
Object.keys(grouped_summary).forEach(group_name => {
|
||||||
|
stats_html += `<h5 style="margin-top: 15px; margin-bottom: 10px; color: #d63384;">${group_name}</h5>`;
|
||||||
|
stats_html += '<div class="row">';
|
||||||
|
|
||||||
|
grouped_summary[group_name].forEach((item, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
stats_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
stats_html += '<div class="col-md-6" style="margin-bottom: 10px;">';
|
||||||
|
stats_html += `<div style="padding: 12px; border: 2px solid #e9ecef; border-left: 4px solid #6610f2; border-radius: 6px; background: white; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">`;
|
||||||
|
stats_html += `<strong style="color: #6610f2;">${item.article}</strong><br>`;
|
||||||
|
stats_html += `<small style="color: #6c757d;">Aktivlər: <strong>${item.assets_count}</strong> | Başlanğıc: <strong>${item.total_value_from.toFixed(2)}</strong> | Son: <strong>${item.total_value_to.toFixed(2)}</strong> | Sığorta: <strong>${item.total_insured.toFixed(2)}</strong></small>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
stats_html += `<div style="margin-top: 20px; padding: 15px; border-top: 3px solid #6610f2; background: linear-gradient(135deg, #6610f210 0%, #fff 100%);">`;
|
||||||
|
stats_html += `<div class="row text-center">`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #6610f2; font-size: 14px; font-weight: bold;">⚖️ Cəmi aktivlər<br><span style="font-size: 18px;">${totals.total_assets}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #6610f2; font-size: 14px; font-weight: bold;">💰 Başlanğıc qalıq<br><span style="font-size: 18px;">${totals.total_value_from.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #198754; font-size: 14px; font-weight: bold;">💎 Son qalıq<br><span style="font-size: 18px;">${totals.total_value_to.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #d63384; font-size: 14px; font-weight: bold;">🛡️ Ümumi sığorta<br><span style="font-size: 18px;">${totals.total_insured.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
|
||||||
|
// Удаляем предыдущую статистику если есть
|
||||||
|
$('.tax-exempt-establishment-year-statistics').remove();
|
||||||
|
|
||||||
|
// Добавляем новую статистику
|
||||||
|
$(stats_html).insertAfter('.datatable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группировка статей по типам
|
||||||
|
function group_summary_by_tax_article_type(summary) {
|
||||||
|
let grouped = {
|
||||||
|
'Maddə 199.1 (Azaldılmalı)': [],
|
||||||
|
'Maddə 199.4 (İstisnalar)': [],
|
||||||
|
'Maddə 199.5-199.20 (Xüsusi)': [],
|
||||||
|
'Maddə 227.1 (Digər)': [],
|
||||||
|
'Beynəlxalq müqavilələr': []
|
||||||
|
};
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
if (item.article.includes('199.1')) {
|
||||||
|
grouped['Maddə 199.1 (Azaldılmalı)'].push(item);
|
||||||
|
} else if (item.article.includes('199.4')) {
|
||||||
|
grouped['Maddə 199.4 (İstisnalar)'].push(item);
|
||||||
|
} else if (item.article.match(/199\.(5|7|8|9|11|14|15|16|17|18|19|20)/)) {
|
||||||
|
grouped['Maddə 199.5-199.20 (Xüsusi)'].push(item);
|
||||||
|
} else if (item.article.includes('227.1')) {
|
||||||
|
grouped['Maddə 227.1 (Digər)'].push(item);
|
||||||
|
} else {
|
||||||
|
grouped['Beynəlxalq müqavilələr'].push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Удаляем пустые группы
|
||||||
|
Object.keys(grouped).forEach(key => {
|
||||||
|
if (grouped[key].length === 0) {
|
||||||
|
delete grouped[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return grouped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательные функции
|
||||||
|
|
||||||
|
function get_tax_articles_list() {
|
||||||
|
return [
|
||||||
|
{short_name: "199.1 (Azaldılmalı)", full_name: "Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən, azaldılmalı əmlak vergisinin məbləği"},
|
||||||
|
{short_name: "199.4.1", full_name: "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.2", full_name: "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.3", full_name: "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.4", full_name: "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.1-1", full_name: "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən"},
|
||||||
|
{short_name: "199.5", full_name: "Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.7", full_name: "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.8", full_name: "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.9", full_name: "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən"},
|
||||||
|
{short_name: "199.11", full_name: "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.14", full_name: "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.15", full_name: "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.16", full_name: "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən"},
|
||||||
|
{short_name: "199.17", full_name: "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.18", full_name: "Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.19", full_name: "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən"},
|
||||||
|
{short_name: "199.20", full_name: "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "227.1", full_name: "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "Pay Bölgüsü", full_name: "Qanunla təsdiq olunmuş hasilatın pay bölgüsü haqqında, əsas boru kəməri haqqında və digər bu qəbildən olan sazişlərdə və ya qanunlarda, o cümlədən neft və qaz haqqında, ixrac məqsədli neft-qaz fəaliyyəti üzrə"},
|
||||||
|
{short_name: "İqtisadi Zonalar", full_name: "Xüsusi iqtisadi zonalar haqqında qanunlarda nəzərdə tutulan əmlaklar üzrə"},
|
||||||
|
{short_name: "Beynəlxalq", full_name: "Azərbaycan Respublikasının tərəfdar çıxdığı beynəlxalq müqavilələr üzrə"}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_field_key_js(tax_article) {
|
||||||
|
// Дублируем логику из Python для создания ключей полей
|
||||||
|
if (!tax_article) {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tax_article.includes("199.1-ci") && tax_article.includes("azaldılmalı")) {
|
||||||
|
return "article_199_1_reduced";
|
||||||
|
} else if (tax_article.includes("199.4.1-1-ci")) {
|
||||||
|
return "article_199_4_1_1";
|
||||||
|
} else if (tax_article.includes("199.4.1-ci")) {
|
||||||
|
return "article_199_4_1";
|
||||||
|
} else if (tax_article.includes("199.4.2-ci")) {
|
||||||
|
return "article_199_4_2";
|
||||||
|
} else if (tax_article.includes("199.4.3-cü")) {
|
||||||
|
return "article_199_4_3";
|
||||||
|
} else if (tax_article.includes("199.4.4-cü")) {
|
||||||
|
return "article_199_4_4";
|
||||||
|
} else if (tax_article.includes("199.5-ci")) {
|
||||||
|
return "article_199_5";
|
||||||
|
} else if (tax_article.includes("199.7-ci")) {
|
||||||
|
return "article_199_7";
|
||||||
|
} else if (tax_article.includes("199.8-ci")) {
|
||||||
|
return "article_199_8";
|
||||||
|
} else if (tax_article.includes("199.9-cu")) {
|
||||||
|
return "article_199_9";
|
||||||
|
} else if (tax_article.includes("199.11-ci")) {
|
||||||
|
return "article_199_11";
|
||||||
|
} else if (tax_article.includes("199.14-cü")) {
|
||||||
|
return "article_199_14";
|
||||||
|
} else if (tax_article.includes("199.15-ci")) {
|
||||||
|
return "article_199_15";
|
||||||
|
} else if (tax_article.includes("199.16-cı")) {
|
||||||
|
return "article_199_16";
|
||||||
|
} else if (tax_article.includes("199.17-ci")) {
|
||||||
|
return "article_199_17";
|
||||||
|
} else if (tax_article.includes("199.18-ci")) {
|
||||||
|
return "article_199_18";
|
||||||
|
} else if (tax_article.includes("199.19-cu")) {
|
||||||
|
return "article_199_19";
|
||||||
|
} else if (tax_article.includes("199.20-ci")) {
|
||||||
|
return "article_199_20";
|
||||||
|
} else if (tax_article.includes("227.1-ci")) {
|
||||||
|
return "article_227_1";
|
||||||
|
} else if (tax_article.includes("pay bölgüsü")) {
|
||||||
|
return "article_profit_sharing";
|
||||||
|
} else if (tax_article.includes("iqtisadi zonalar")) {
|
||||||
|
return "article_economic_zones";
|
||||||
|
} else if (tax_article.includes("beynəlxalq müqavilələr")) {
|
||||||
|
return "article_international";
|
||||||
|
} else {
|
||||||
|
return "article_other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2025-09-18 14:57:53.963296",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letterhead": null,
|
||||||
|
"modified": "2025-09-18 14:57:53.963296",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Taxes Az",
|
||||||
|
"name": "Tax Exempt Assets Establishment Year Report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Asset",
|
||||||
|
"report_name": "Tax Exempt Assets Establishment Year Report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Quality Manager"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,423 @@
|
||||||
|
# Copyright (c) 2024, Your Company and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import add_days, flt, formatdate
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
filters.day_before_from_date = add_days(filters.from_date, -1)
|
||||||
|
columns, data = get_columns(filters), get_data(filters)
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
"""Получаем данные по активам с tax exempt статьями года создания компании"""
|
||||||
|
|
||||||
|
# Список всех tax exempt статей
|
||||||
|
tax_exempt_articles = get_tax_exempt_articles_list()
|
||||||
|
|
||||||
|
# Получаем активы с этими статьями (только год создания компании)
|
||||||
|
assets_data = get_establishment_year_tax_exempt_assets(filters, tax_exempt_articles)
|
||||||
|
|
||||||
|
if not assets_data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Получаем расчеты остатков для этих активов
|
||||||
|
asset_balances = get_asset_balances(filters, [asset['name'] for asset in assets_data])
|
||||||
|
|
||||||
|
# Формируем итоговые данные
|
||||||
|
data = []
|
||||||
|
|
||||||
|
for asset in assets_data:
|
||||||
|
row = frappe._dict()
|
||||||
|
|
||||||
|
# Основные данные актива
|
||||||
|
row.asset = asset['name']
|
||||||
|
row.purchase_date = asset['purchase_date']
|
||||||
|
row.tax_exempt_tax_article = asset['tax_exempt_tax_article']
|
||||||
|
row.insured_value = flt(asset.get('insured_value', 0))
|
||||||
|
|
||||||
|
# Находим баланс для этого актива
|
||||||
|
asset_balance = next((bal for bal in asset_balances if bal['asset'] == asset['name']), {})
|
||||||
|
|
||||||
|
# Рассчитываем остатки на начало и конец периода
|
||||||
|
value_as_on_from_date = flt(asset_balance.get('value_as_on_from_date', 0))
|
||||||
|
value_of_new_purchase = flt(asset_balance.get('value_of_new_purchase', 0))
|
||||||
|
value_of_sold_asset = flt(asset_balance.get('value_of_sold_asset', 0))
|
||||||
|
value_of_scrapped_asset = flt(asset_balance.get('value_of_scrapped_asset', 0))
|
||||||
|
value_of_capitalized_asset = flt(asset_balance.get('value_of_capitalized_asset', 0))
|
||||||
|
|
||||||
|
value_as_on_to_date = (
|
||||||
|
value_as_on_from_date +
|
||||||
|
value_of_new_purchase -
|
||||||
|
value_of_sold_asset -
|
||||||
|
value_of_scrapped_asset -
|
||||||
|
value_of_capitalized_asset
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализируем все колонки нулями
|
||||||
|
for article in tax_exempt_articles:
|
||||||
|
article_key = get_field_key(article)
|
||||||
|
row[f"{article_key}_value_from"] = 0
|
||||||
|
row[f"{article_key}_value_to"] = 0
|
||||||
|
row[f"{article_key}_insured"] = 0
|
||||||
|
|
||||||
|
# Заполняем колонки для соответствующей статьи
|
||||||
|
if asset['tax_exempt_tax_article']:
|
||||||
|
article_key = get_field_key(asset['tax_exempt_tax_article'])
|
||||||
|
row[f"{article_key}_value_from"] = value_as_on_from_date
|
||||||
|
row[f"{article_key}_value_to"] = value_as_on_to_date
|
||||||
|
row[f"{article_key}_insured"] = row.insured_value
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_tax_exempt_articles_list():
|
||||||
|
"""Возвращает список всех tax exempt статей"""
|
||||||
|
return [
|
||||||
|
"Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən, azaldılmalı əmlak vergisinin məbləği",
|
||||||
|
"Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən",
|
||||||
|
"Qanunla təsdiq olunmuş hasilatın pay bölgüsü haqqında, əsas boru kəməri haqqında və digər bu qəbildən olan sazişlərdə və ya qanunlarda, o cümlədən neft və qaz haqqında, ixrac məqsədli neft-qaz fəaliyyəti üzrə",
|
||||||
|
"Xüsusi iqtisadi zonalar haqqında qanunlarda nəzərdə tutulan əmlaklar üzrə",
|
||||||
|
"Azərbaycan Respublikasının tərəfdar çıxdığı beynəlxalq müqavilələr üzrə"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_field_key(tax_article):
|
||||||
|
"""Создает ключ поля на основе названия tax article"""
|
||||||
|
if not tax_article:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
# Извлекаем номер статьи для создания короткого ключа
|
||||||
|
if "199.1-ci" in tax_article and "azaldılmalı" in tax_article:
|
||||||
|
return "article_199_1_reduced"
|
||||||
|
elif "199.4.1-ci" in tax_article:
|
||||||
|
return "article_199_4_1"
|
||||||
|
elif "199.4.2-ci" in tax_article:
|
||||||
|
return "article_199_4_2"
|
||||||
|
elif "199.4.3-cü" in tax_article:
|
||||||
|
return "article_199_4_3"
|
||||||
|
elif "199.4.4-cü" in tax_article:
|
||||||
|
return "article_199_4_4"
|
||||||
|
elif "199.4.1-1-ci" in tax_article:
|
||||||
|
return "article_199_4_1_1"
|
||||||
|
elif "199.5-ci" in tax_article:
|
||||||
|
return "article_199_5"
|
||||||
|
elif "199.7-ci" in tax_article:
|
||||||
|
return "article_199_7"
|
||||||
|
elif "199.8-ci" in tax_article:
|
||||||
|
return "article_199_8"
|
||||||
|
elif "199.9-cu" in tax_article:
|
||||||
|
return "article_199_9"
|
||||||
|
elif "199.11-ci" in tax_article:
|
||||||
|
return "article_199_11"
|
||||||
|
elif "199.14-cü" in tax_article:
|
||||||
|
return "article_199_14"
|
||||||
|
elif "199.15-ci" in tax_article:
|
||||||
|
return "article_199_15"
|
||||||
|
elif "199.16-cı" in tax_article:
|
||||||
|
return "article_199_16"
|
||||||
|
elif "199.17-ci" in tax_article:
|
||||||
|
return "article_199_17"
|
||||||
|
elif "199.18-ci" in tax_article:
|
||||||
|
return "article_199_18"
|
||||||
|
elif "199.19-cu" in tax_article:
|
||||||
|
return "article_199_19"
|
||||||
|
elif "199.20-ci" in tax_article:
|
||||||
|
return "article_199_20"
|
||||||
|
elif "227.1-ci" in tax_article:
|
||||||
|
return "article_227_1"
|
||||||
|
elif "pay bölgüsü" in tax_article:
|
||||||
|
return "article_profit_sharing"
|
||||||
|
elif "iqtisadi zonalar" in tax_article:
|
||||||
|
return "article_economic_zones"
|
||||||
|
elif "beynəlxalq müqavilələr" in tax_article:
|
||||||
|
return "article_international"
|
||||||
|
else:
|
||||||
|
return "article_other"
|
||||||
|
|
||||||
|
|
||||||
|
def get_establishment_year_tax_exempt_assets(filters, tax_exempt_articles):
|
||||||
|
"""Получает активы с tax exempt статьями ТОЛЬКО года создания компании"""
|
||||||
|
|
||||||
|
conditions = []
|
||||||
|
values = []
|
||||||
|
|
||||||
|
# Фильтр по компании
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions.append("a.company = %s")
|
||||||
|
values.append(filters.get("company"))
|
||||||
|
|
||||||
|
# Фильтр по датам
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions.append("a.purchase_date <= %s")
|
||||||
|
values.append(filters.get("to_date"))
|
||||||
|
|
||||||
|
# Фильтр по tax exempt статьям
|
||||||
|
article_placeholders = ", ".join(["%s"] * len(tax_exempt_articles))
|
||||||
|
conditions.append(f"a.tax_exempt_tax_article IN ({article_placeholders})")
|
||||||
|
values.extend(tax_exempt_articles)
|
||||||
|
|
||||||
|
# Только подтвержденные активы
|
||||||
|
conditions.append("a.docstatus = 1")
|
||||||
|
|
||||||
|
# ТОЛЬКО активы года создания компании
|
||||||
|
conditions.append("YEAR(a.purchase_date) = YEAR(c.date_of_establishment)")
|
||||||
|
|
||||||
|
where_clause = ""
|
||||||
|
if conditions:
|
||||||
|
where_clause = "WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
# Исключаем капитализированные активы (как в стандартном отчете)
|
||||||
|
exclude_capitalized = """
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
where_clause += exclude_capitalized
|
||||||
|
values.append(filters.get("from_date"))
|
||||||
|
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name,
|
||||||
|
a.purchase_date,
|
||||||
|
a.tax_exempt_tax_article,
|
||||||
|
a.insured_value
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
JOIN
|
||||||
|
`tabCompany` c ON a.company = c.name
|
||||||
|
{where_clause}
|
||||||
|
ORDER BY
|
||||||
|
a.purchase_date DESC, a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_balances(filters, asset_names):
|
||||||
|
"""Рассчитывает остатки активов на основе стандартной логики"""
|
||||||
|
|
||||||
|
if not asset_names:
|
||||||
|
return []
|
||||||
|
|
||||||
|
asset_placeholders = ", ".join(["%s"] * len(asset_names))
|
||||||
|
|
||||||
|
# Используем ту же логику что в стандартном отчете для расчета остатков
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name as asset,
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date < %s THEN
|
||||||
|
CASE WHEN IFNULL(a.disposal_date, 0) = 0 OR a.disposal_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_as_on_from_date,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_new_purchase,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Sold" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_sold_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Scrapped" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_scrapped_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Capitalized" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_capitalized_asset
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
WHERE
|
||||||
|
a.docstatus = 1
|
||||||
|
AND a.company = %s
|
||||||
|
AND a.purchase_date <= %s
|
||||||
|
AND a.name IN ({asset_placeholders})
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
GROUP BY a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = [
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 1
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 2
|
||||||
|
filters.get("from_date"), # value_of_new_purchase
|
||||||
|
filters.get("from_date"), # value_of_sold_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_sold_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_scrapped_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_scrapped_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_capitalized_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_capitalized_asset condition 2
|
||||||
|
filters.get("company"), # company filter
|
||||||
|
filters.get("to_date"), # purchase_date filter
|
||||||
|
*asset_names, # asset names for IN clause
|
||||||
|
filters.get("from_date") # capitalization exclusion
|
||||||
|
]
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns(filters):
|
||||||
|
"""Создает колонки отчета"""
|
||||||
|
columns = []
|
||||||
|
|
||||||
|
# Основные колонки
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": "Əmlak",
|
||||||
|
"fieldname": "asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Asset",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Tarix",
|
||||||
|
"fieldname": "purchase_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# Создаем колонки для каждого tax article
|
||||||
|
tax_exempt_articles = get_tax_exempt_articles_list()
|
||||||
|
|
||||||
|
for article in tax_exempt_articles:
|
||||||
|
article_key = get_field_key(article)
|
||||||
|
|
||||||
|
# Сокращенное название для заголовка колонки
|
||||||
|
short_name = get_short_article_name(article)
|
||||||
|
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.day_before_from_date) + " əsasən",
|
||||||
|
"fieldname": f"{article_key}_value_from",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.to_date) + " əsasən",
|
||||||
|
"fieldname": f"{article_key}_value_to",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Sığorta dəyəri",
|
||||||
|
"fieldname": f"{article_key}_insured",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
||||||
|
def get_short_article_name(tax_article):
|
||||||
|
"""Создает короткое название для заголовка колонки"""
|
||||||
|
if "199.1-ci" in tax_article and "azaldılmalı" in tax_article:
|
||||||
|
return "199.1 (Azaldılmalı)"
|
||||||
|
elif "199.4.1-1-ci" in tax_article:
|
||||||
|
return "199.4.1-1"
|
||||||
|
elif "199.4.1-ci" in tax_article:
|
||||||
|
return "199.4.1"
|
||||||
|
elif "199.4.2-ci" in tax_article:
|
||||||
|
return "199.4.2"
|
||||||
|
elif "199.4.3-cü" in tax_article:
|
||||||
|
return "199.4.3"
|
||||||
|
elif "199.4.4-cü" in tax_article:
|
||||||
|
return "199.4.4"
|
||||||
|
elif "199.5-ci" in tax_article:
|
||||||
|
return "199.5"
|
||||||
|
elif "199.7-ci" in tax_article:
|
||||||
|
return "199.7"
|
||||||
|
elif "199.8-ci" in tax_article:
|
||||||
|
return "199.8"
|
||||||
|
elif "199.9-cu" in tax_article:
|
||||||
|
return "199.9"
|
||||||
|
elif "199.11-ci" in tax_article:
|
||||||
|
return "199.11"
|
||||||
|
elif "199.14-cü" in tax_article:
|
||||||
|
return "199.14"
|
||||||
|
elif "199.15-ci" in tax_article:
|
||||||
|
return "199.15"
|
||||||
|
elif "199.16-cı" in tax_article:
|
||||||
|
return "199.16"
|
||||||
|
elif "199.17-ci" in tax_article:
|
||||||
|
return "199.17"
|
||||||
|
elif "199.18-ci" in tax_article:
|
||||||
|
return "199.18"
|
||||||
|
elif "199.19-cu" in tax_article:
|
||||||
|
return "199.19"
|
||||||
|
elif "199.20-ci" in tax_article:
|
||||||
|
return "199.20"
|
||||||
|
elif "227.1-ci" in tax_article:
|
||||||
|
return "227.1"
|
||||||
|
elif "pay bölgüsü" in tax_article:
|
||||||
|
return "Pay Bölgüsü"
|
||||||
|
elif "iqtisadi zonalar" in tax_article:
|
||||||
|
return "İqtisadi Zonalar"
|
||||||
|
elif "beynəlxalq müqavilələr" in tax_article:
|
||||||
|
return "Beynəlxalq"
|
||||||
|
else:
|
||||||
|
return "Digər"
|
||||||
|
|
@ -0,0 +1,363 @@
|
||||||
|
// Copyright (c) 2024, Your Company and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.query_reports["Tax Exempt Assets Report"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatter": function (value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
// Подсветка колонок с остатками и страховкой
|
||||||
|
if (column.fieldname && column.fieldname.includes("value_")) {
|
||||||
|
if (value && parseFloat(value) > 0) {
|
||||||
|
// Разные цвета для разных типов колонок
|
||||||
|
let color = "#28a745"; // зеленый по умолчанию
|
||||||
|
|
||||||
|
if (column.fieldname.includes("_value_from")) {
|
||||||
|
color = "#17a2b8"; // голубой для начальных остатков
|
||||||
|
} else if (column.fieldname.includes("_value_to")) {
|
||||||
|
color = "#28a745"; // зеленый для конечных остатков
|
||||||
|
} else if (column.fieldname.includes("_insured")) {
|
||||||
|
color = "#ffc107"; // желтый для страховки
|
||||||
|
}
|
||||||
|
|
||||||
|
value = `<span style="color: ${color}; font-weight: bold; background-color: ${color}15; padding: 2px 6px; border-radius: 3px;">${value}</span>`;
|
||||||
|
} else if (value == 0 || !value) {
|
||||||
|
value = `<span style="color: #ccc;">0.00</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Asset колонки
|
||||||
|
if (column.fieldname == "asset" && value) {
|
||||||
|
value = `<span style="color: #007bff; font-weight: bold;">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Date колонки
|
||||||
|
if (column.fieldname == "purchase_date" && value) {
|
||||||
|
value = `<span style="color: #6c757d; font-weight: 500;">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
"onload": function(report) {
|
||||||
|
// Добавляем кастомные кнопки
|
||||||
|
report.page.add_inner_button(__("Export Tax Summary"), function() {
|
||||||
|
export_tax_summary(report);
|
||||||
|
});
|
||||||
|
|
||||||
|
report.page.add_inner_button(__("Show Tax Articles"), function() {
|
||||||
|
show_tax_articles_info();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"after_datatable_render": function(datatable_obj) {
|
||||||
|
// Добавляем итоговую статистику
|
||||||
|
setTimeout(() => {
|
||||||
|
add_tax_statistics(datatable_obj);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Функция экспорта сводки по налоговым статьям
|
||||||
|
function export_tax_summary(report) {
|
||||||
|
let data = report.data;
|
||||||
|
let summary = calculate_tax_totals(data);
|
||||||
|
|
||||||
|
// Создаем CSV с итогами по налоговым статьям
|
||||||
|
let csv_content = "Tax Article,Assets Count,Total Value From,Total Value To,Total Insured Value\n";
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
csv_content += `"${item.article}",${item.assets_count},${item.total_value_from},${item.total_value_to},${item.total_insured}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
csv_content += `\n"TOTAL",${totals.total_assets},${totals.total_value_from},${totals.total_value_to},${totals.total_insured}\n`;
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'tax_exempt_summary_' + frappe.datetime.get_today() + '.csv';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
frappe.show_alert({message: __("Tax summary exported successfully"), indicator: "green"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция расчета итогов по налоговым статьям
|
||||||
|
function calculate_tax_totals(data) {
|
||||||
|
let tax_articles = get_tax_articles_list();
|
||||||
|
let summary = [];
|
||||||
|
|
||||||
|
tax_articles.forEach(article => {
|
||||||
|
let article_key = get_field_key_js(article.full_name);
|
||||||
|
let assets_count = 0;
|
||||||
|
let total_value_from = 0;
|
||||||
|
let total_value_to = 0;
|
||||||
|
let total_insured = 0;
|
||||||
|
|
||||||
|
data.forEach(row => {
|
||||||
|
let value_from = row[`${article_key}_value_from`] || 0;
|
||||||
|
let value_to = row[`${article_key}_value_to`] || 0;
|
||||||
|
let insured = row[`${article_key}_insured`] || 0;
|
||||||
|
|
||||||
|
if (value_from > 0 || value_to > 0 || insured > 0) {
|
||||||
|
assets_count++;
|
||||||
|
total_value_from += value_from;
|
||||||
|
total_value_to += value_to;
|
||||||
|
total_insured += insured;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assets_count > 0) {
|
||||||
|
summary.push({
|
||||||
|
article: article.short_name,
|
||||||
|
assets_count: assets_count,
|
||||||
|
total_value_from: total_value_from,
|
||||||
|
total_value_to: total_value_to,
|
||||||
|
total_insured: total_insured
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция показа информации о налоговых статьях
|
||||||
|
function show_tax_articles_info() {
|
||||||
|
let tax_articles = get_tax_articles_list();
|
||||||
|
let info_html = '<div class="tax-articles-info">';
|
||||||
|
info_html += '<h4>📋 Налоговые статьи в отчете:</h4>';
|
||||||
|
info_html += '<div class="row">';
|
||||||
|
|
||||||
|
tax_articles.forEach((article, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
info_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
info_html += '<div class="col-md-6" style="margin-bottom: 8px;">';
|
||||||
|
info_html += `<strong>${article.short_name}:</strong><br>`;
|
||||||
|
info_html += `<small style="color: #6c757d;">${article.full_name}</small>`;
|
||||||
|
info_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
info_html += '</div></div>';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Tax Articles Information"),
|
||||||
|
message: info_html,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция добавления статистики под таблицу
|
||||||
|
function add_tax_statistics(datatable_obj) {
|
||||||
|
if (datatable_obj && datatable_obj.data) {
|
||||||
|
let summary = calculate_tax_totals(datatable_obj.data);
|
||||||
|
|
||||||
|
let stats_html = '<div class="tax-statistics" style="margin-top: 20px; padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #dee2e6;">';
|
||||||
|
stats_html += '<h4 style="margin-bottom: 15px; color: #495057;">📊 Сводка по налоговым статьям:</h4>';
|
||||||
|
|
||||||
|
// Группируем по типам статей
|
||||||
|
let grouped_summary = group_summary_by_type(summary);
|
||||||
|
|
||||||
|
Object.keys(grouped_summary).forEach(group_name => {
|
||||||
|
stats_html += `<h5 style="margin-top: 15px; margin-bottom: 10px; color: #495057;">${group_name}</h5>`;
|
||||||
|
stats_html += '<div class="row">';
|
||||||
|
|
||||||
|
grouped_summary[group_name].forEach((item, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
stats_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
stats_html += '<div class="col-md-6" style="margin-bottom: 10px;">';
|
||||||
|
stats_html += `<div style="padding: 10px; border: 1px solid #dee2e6; border-radius: 4px; background: white;">`;
|
||||||
|
stats_html += `<strong>${item.article}</strong><br>`;
|
||||||
|
stats_html += `<small>Активов: ${item.assets_count} | От: ${item.total_value_from.toFixed(2)} | До: ${item.total_value_to.toFixed(2)} | Страховка: ${item.total_insured.toFixed(2)}</small>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
stats_html += `<div style="margin-top: 20px; padding-top: 15px; border-top: 2px solid #007bff;">`;
|
||||||
|
stats_html += `<div class="row">`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Всего активов: ${totals.total_assets}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Остаток на начало: ${totals.total_value_from.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Остаток на конец: ${totals.total_value_to.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Всего страховки: ${totals.total_insured.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
|
||||||
|
// Удаляем предыдущую статистику если есть
|
||||||
|
$('.tax-statistics').remove();
|
||||||
|
|
||||||
|
// Добавляем новую статистику
|
||||||
|
$(stats_html).insertAfter('.datatable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группировка статей по типам
|
||||||
|
function group_summary_by_type(summary) {
|
||||||
|
let grouped = {
|
||||||
|
'Статья 199.1 (Льготы)': [],
|
||||||
|
'Статьи 199.4 (Исключения)': [],
|
||||||
|
'Статьи 199.5-199.20 (Специальные)': [],
|
||||||
|
'Статья 227.1 (Прочие)': [],
|
||||||
|
'Международные соглашения': []
|
||||||
|
};
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
if (item.article.includes('199.1')) {
|
||||||
|
grouped['Статья 199.1 (Льготы)'].push(item);
|
||||||
|
} else if (item.article.includes('199.4')) {
|
||||||
|
grouped['Статьи 199.4 (Исключения)'].push(item);
|
||||||
|
} else if (item.article.match(/199\.(5|7|8|9|11|14|15|16|17|18|19|20)/)) {
|
||||||
|
grouped['Статьи 199.5-199.20 (Специальные)'].push(item);
|
||||||
|
} else if (item.article.includes('227.1')) {
|
||||||
|
grouped['Статья 227.1 (Прочие)'].push(item);
|
||||||
|
} else {
|
||||||
|
grouped['Международные соглашения'].push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Удаляем пустые группы
|
||||||
|
Object.keys(grouped).forEach(key => {
|
||||||
|
if (grouped[key].length === 0) {
|
||||||
|
delete grouped[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return grouped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательные функции
|
||||||
|
|
||||||
|
function get_tax_articles_list() {
|
||||||
|
return [
|
||||||
|
{short_name: "199.1 (Reduced)", full_name: "Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən, azaldılmalı əmlak vergisinin məbləği"},
|
||||||
|
{short_name: "199.4.1", full_name: "Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.2", full_name: "Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.3", full_name: "Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.4", full_name: "Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.4.1-1", full_name: "Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən"},
|
||||||
|
{short_name: "199.5", full_name: "Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.7", full_name: "Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.8", full_name: "Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.9", full_name: "Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən"},
|
||||||
|
{short_name: "199.11", full_name: "Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.14", full_name: "Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən"},
|
||||||
|
{short_name: "199.15", full_name: "Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.16", full_name: "Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən"},
|
||||||
|
{short_name: "199.17", full_name: "Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.18", full_name: "Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "199.19", full_name: "Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən"},
|
||||||
|
{short_name: "199.20", full_name: "Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "227.1", full_name: "Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən"},
|
||||||
|
{short_name: "Profit Sharing", full_name: "Qanunla təsdiq olunmuş hasilatın pay bölgüsü haqqında, əsas boru kəməri haqqında və digər bu qəbildən olan sazişlərdə və ya qanunlarda, o cümlədən neft və qaz haqqında, ixrac məqsədli neft-qaz fəaliyyəti üzrə"},
|
||||||
|
{short_name: "Economic Zones", full_name: "Xüsusi iqtisadi zonalar haqqında qanunlarda nəzərdə tutulan əmlaklar üzrə"},
|
||||||
|
{short_name: "International", full_name: "Azərbaycan Respublikasının tərəfdar çıxdığı beynəlxalq müqavilələr üzrə"}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_field_key_js(tax_article) {
|
||||||
|
// Дублируем логику из Python для создания ключей полей
|
||||||
|
if (!tax_article) {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tax_article.includes("199.1-ci") && tax_article.includes("azaldılmalı")) {
|
||||||
|
return "article_199_1_reduced";
|
||||||
|
} else if (tax_article.includes("199.4.1-1-ci")) {
|
||||||
|
return "article_199_4_1_1";
|
||||||
|
} else if (tax_article.includes("199.4.1-ci")) {
|
||||||
|
return "article_199_4_1";
|
||||||
|
} else if (tax_article.includes("199.4.2-ci")) {
|
||||||
|
return "article_199_4_2";
|
||||||
|
} else if (tax_article.includes("199.4.3-cü")) {
|
||||||
|
return "article_199_4_3";
|
||||||
|
} else if (tax_article.includes("199.4.4-cü")) {
|
||||||
|
return "article_199_4_4";
|
||||||
|
} else if (tax_article.includes("199.5-ci")) {
|
||||||
|
return "article_199_5";
|
||||||
|
} else if (tax_article.includes("199.7-ci")) {
|
||||||
|
return "article_199_7";
|
||||||
|
} else if (tax_article.includes("199.8-ci")) {
|
||||||
|
return "article_199_8";
|
||||||
|
} else if (tax_article.includes("199.9-cu")) {
|
||||||
|
return "article_199_9";
|
||||||
|
} else if (tax_article.includes("199.11-ci")) {
|
||||||
|
return "article_199_11";
|
||||||
|
} else if (tax_article.includes("199.14-cü")) {
|
||||||
|
return "article_199_14";
|
||||||
|
} else if (tax_article.includes("199.15-ci")) {
|
||||||
|
return "article_199_15";
|
||||||
|
} else if (tax_article.includes("199.16-cı")) {
|
||||||
|
return "article_199_16";
|
||||||
|
} else if (tax_article.includes("199.17-ci")) {
|
||||||
|
return "article_199_17";
|
||||||
|
} else if (tax_article.includes("199.18-ci")) {
|
||||||
|
return "article_199_18";
|
||||||
|
} else if (tax_article.includes("199.19-cu")) {
|
||||||
|
return "article_199_19";
|
||||||
|
} else if (tax_article.includes("199.20-ci")) {
|
||||||
|
return "article_199_20";
|
||||||
|
} else if (tax_article.includes("227.1-ci")) {
|
||||||
|
return "article_227_1";
|
||||||
|
} else if (tax_article.includes("pay bölgüsü")) {
|
||||||
|
return "article_profit_sharing";
|
||||||
|
} else if (tax_article.includes("iqtisadi zonalar")) {
|
||||||
|
return "article_economic_zones";
|
||||||
|
} else if (tax_article.includes("beynəlxalq müqavilələr")) {
|
||||||
|
return "article_international";
|
||||||
|
} else {
|
||||||
|
return "article_other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2025-09-17 17:34:58.126343",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letterhead": null,
|
||||||
|
"modified": "2025-09-17 17:34:58.126343",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Taxes Az",
|
||||||
|
"name": "Tax Exempt Assets Report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Asset",
|
||||||
|
"report_name": "Tax Exempt Assets Report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Quality Manager"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,423 @@
|
||||||
|
# Copyright (c) 2024, Your Company and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import add_days, flt, formatdate
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
filters.day_before_from_date = add_days(filters.from_date, -1)
|
||||||
|
columns, data = get_columns(filters), get_data(filters)
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
"""Получаем данные по активам с tax exempt статьями"""
|
||||||
|
|
||||||
|
# Список всех tax exempt статей
|
||||||
|
tax_exempt_articles = get_tax_exempt_articles_list()
|
||||||
|
|
||||||
|
# Получаем активы с этими статьями
|
||||||
|
assets_data = get_assets_with_tax_exempt_articles(filters, tax_exempt_articles)
|
||||||
|
|
||||||
|
if not assets_data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Получаем расчеты остатков для этих активов
|
||||||
|
asset_balances = get_asset_balances(filters, [asset['name'] for asset in assets_data])
|
||||||
|
|
||||||
|
# Формируем итоговые данные
|
||||||
|
data = []
|
||||||
|
|
||||||
|
for asset in assets_data:
|
||||||
|
row = frappe._dict()
|
||||||
|
|
||||||
|
# Основные данные актива
|
||||||
|
row.asset = asset['name']
|
||||||
|
row.purchase_date = asset['purchase_date']
|
||||||
|
row.tax_exempt_tax_article = asset['tax_exempt_tax_article']
|
||||||
|
row.insured_value = flt(asset.get('insured_value', 0))
|
||||||
|
|
||||||
|
# Находим баланс для этого актива
|
||||||
|
asset_balance = next((bal for bal in asset_balances if bal['asset'] == asset['name']), {})
|
||||||
|
|
||||||
|
# Рассчитываем остатки на начало и конец периода
|
||||||
|
value_as_on_from_date = flt(asset_balance.get('value_as_on_from_date', 0))
|
||||||
|
value_of_new_purchase = flt(asset_balance.get('value_of_new_purchase', 0))
|
||||||
|
value_of_sold_asset = flt(asset_balance.get('value_of_sold_asset', 0))
|
||||||
|
value_of_scrapped_asset = flt(asset_balance.get('value_of_scrapped_asset', 0))
|
||||||
|
value_of_capitalized_asset = flt(asset_balance.get('value_of_capitalized_asset', 0))
|
||||||
|
|
||||||
|
value_as_on_to_date = (
|
||||||
|
value_as_on_from_date +
|
||||||
|
value_of_new_purchase -
|
||||||
|
value_of_sold_asset -
|
||||||
|
value_of_scrapped_asset -
|
||||||
|
value_of_capitalized_asset
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализируем все колонки нулями
|
||||||
|
for article in tax_exempt_articles:
|
||||||
|
article_key = get_field_key(article)
|
||||||
|
row[f"{article_key}_value_from"] = 0
|
||||||
|
row[f"{article_key}_value_to"] = 0
|
||||||
|
row[f"{article_key}_insured"] = 0
|
||||||
|
|
||||||
|
# Заполняем колонки для соответствующей статьи
|
||||||
|
if asset['tax_exempt_tax_article']:
|
||||||
|
article_key = get_field_key(asset['tax_exempt_tax_article'])
|
||||||
|
row[f"{article_key}_value_from"] = value_as_on_from_date
|
||||||
|
row[f"{article_key}_value_to"] = value_as_on_to_date
|
||||||
|
row[f"{article_key}_insured"] = row.insured_value
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_tax_exempt_articles_list():
|
||||||
|
"""Возвращает список всех tax exempt статей"""
|
||||||
|
return [
|
||||||
|
"Vergi Məcəlləsinin 199.1-ci maddəsinə əsasən, azaldılmalı əmlak vergisinin məbləği",
|
||||||
|
"Vergi Məcəlləsinin 199.4.1-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.2-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.3-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.4-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.4.1-1-ci madacdəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.5-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.7-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.8-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.9-cu maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.11-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.14-cü maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.15-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.16-cı maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.17-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.18-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.19-cu maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 199.20-ci maddəsinə əsasən",
|
||||||
|
"Vergi Məcəlləsinin 227.1-ci maddəsinə əsasən",
|
||||||
|
"Qanunla təsdiq olunmuş hasilatın pay bölgüsü haqqında, əsas boru kəməri haqqında və digər bu qəbildən olan sazişlərdə və ya qanunlarda, o cümlədən neft və qaz haqqında, ixrac məqsədli neft-qaz fəaliyyəti üzrə",
|
||||||
|
"Xüsusi iqtisadi zonalar haqqında qanunlarda nəzərdə tutulan əmlaklar üzrə",
|
||||||
|
"Azərbaycan Respublikasının tərəfdar çıxdığı beynəlxalq müqavilələr üzrə"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_field_key(tax_article):
|
||||||
|
"""Создает ключ поля на основе названия tax article"""
|
||||||
|
if not tax_article:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
# Извлекаем номер статьи для создания короткого ключа
|
||||||
|
if "199.1-ci" in tax_article and "azaldılmalı" in tax_article:
|
||||||
|
return "article_199_1_reduced"
|
||||||
|
elif "199.4.1-ci" in tax_article:
|
||||||
|
return "article_199_4_1"
|
||||||
|
elif "199.4.2-ci" in tax_article:
|
||||||
|
return "article_199_4_2"
|
||||||
|
elif "199.4.3-cü" in tax_article:
|
||||||
|
return "article_199_4_3"
|
||||||
|
elif "199.4.4-cü" in tax_article:
|
||||||
|
return "article_199_4_4"
|
||||||
|
elif "199.4.1-1-ci" in tax_article:
|
||||||
|
return "article_199_4_1_1"
|
||||||
|
elif "199.5-ci" in tax_article:
|
||||||
|
return "article_199_5"
|
||||||
|
elif "199.7-ci" in tax_article:
|
||||||
|
return "article_199_7"
|
||||||
|
elif "199.8-ci" in tax_article:
|
||||||
|
return "article_199_8"
|
||||||
|
elif "199.9-cu" in tax_article:
|
||||||
|
return "article_199_9"
|
||||||
|
elif "199.11-ci" in tax_article:
|
||||||
|
return "article_199_11"
|
||||||
|
elif "199.14-cü" in tax_article:
|
||||||
|
return "article_199_14"
|
||||||
|
elif "199.15-ci" in tax_article:
|
||||||
|
return "article_199_15"
|
||||||
|
elif "199.16-cı" in tax_article:
|
||||||
|
return "article_199_16"
|
||||||
|
elif "199.17-ci" in tax_article:
|
||||||
|
return "article_199_17"
|
||||||
|
elif "199.18-ci" in tax_article:
|
||||||
|
return "article_199_18"
|
||||||
|
elif "199.19-cu" in tax_article:
|
||||||
|
return "article_199_19"
|
||||||
|
elif "199.20-ci" in tax_article:
|
||||||
|
return "article_199_20"
|
||||||
|
elif "227.1-ci" in tax_article:
|
||||||
|
return "article_227_1"
|
||||||
|
elif "pay bölgüsü" in tax_article:
|
||||||
|
return "article_profit_sharing"
|
||||||
|
elif "iqtisadi zonalar" in tax_article:
|
||||||
|
return "article_economic_zones"
|
||||||
|
elif "beynəlxalq müqavilələr" in tax_article:
|
||||||
|
return "article_international"
|
||||||
|
else:
|
||||||
|
return "article_other"
|
||||||
|
|
||||||
|
|
||||||
|
def get_assets_with_tax_exempt_articles(filters, tax_exempt_articles):
|
||||||
|
"""Получает активы с tax exempt статьями исключая активы года создания компании"""
|
||||||
|
|
||||||
|
conditions = []
|
||||||
|
values = []
|
||||||
|
|
||||||
|
# Фильтр по компании
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions.append("a.company = %s")
|
||||||
|
values.append(filters.get("company"))
|
||||||
|
|
||||||
|
# Фильтр по датам
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions.append("a.purchase_date <= %s")
|
||||||
|
values.append(filters.get("to_date"))
|
||||||
|
|
||||||
|
# Фильтр по tax exempt статьям
|
||||||
|
article_placeholders = ", ".join(["%s"] * len(tax_exempt_articles))
|
||||||
|
conditions.append(f"a.tax_exempt_tax_article IN ({article_placeholders})")
|
||||||
|
values.extend(tax_exempt_articles)
|
||||||
|
|
||||||
|
# Только подтвержденные активы
|
||||||
|
conditions.append("a.docstatus = 1")
|
||||||
|
|
||||||
|
# ИСКЛЮЧАЕМ активы года создания компании
|
||||||
|
conditions.append("YEAR(a.purchase_date) != YEAR(c.date_of_establishment)")
|
||||||
|
|
||||||
|
where_clause = ""
|
||||||
|
if conditions:
|
||||||
|
where_clause = "WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
# Исключаем капитализированные активы (как в стандартном отчете)
|
||||||
|
exclude_capitalized = """
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
where_clause += exclude_capitalized
|
||||||
|
values.append(filters.get("from_date"))
|
||||||
|
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name,
|
||||||
|
a.purchase_date,
|
||||||
|
a.tax_exempt_tax_article,
|
||||||
|
a.insured_value
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
JOIN
|
||||||
|
`tabCompany` c ON a.company = c.name
|
||||||
|
{where_clause}
|
||||||
|
ORDER BY
|
||||||
|
a.purchase_date DESC, a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_balances(filters, asset_names):
|
||||||
|
"""Рассчитывает остатки активов на основе стандартной логики"""
|
||||||
|
|
||||||
|
if not asset_names:
|
||||||
|
return []
|
||||||
|
|
||||||
|
asset_placeholders = ", ".join(["%s"] * len(asset_names))
|
||||||
|
|
||||||
|
# Используем ту же логику что в стандартном отчете для расчета остатков
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name as asset,
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date < %s THEN
|
||||||
|
CASE WHEN IFNULL(a.disposal_date, 0) = 0 OR a.disposal_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_as_on_from_date,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_new_purchase,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Sold" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_sold_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Scrapped" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_scrapped_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Capitalized" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_capitalized_asset
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
WHERE
|
||||||
|
a.docstatus = 1
|
||||||
|
AND a.company = %s
|
||||||
|
AND a.purchase_date <= %s
|
||||||
|
AND a.name IN ({asset_placeholders})
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
GROUP BY a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = [
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 1
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 2
|
||||||
|
filters.get("from_date"), # value_of_new_purchase
|
||||||
|
filters.get("from_date"), # value_of_sold_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_sold_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_scrapped_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_scrapped_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_capitalized_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_capitalized_asset condition 2
|
||||||
|
filters.get("company"), # company filter
|
||||||
|
filters.get("to_date"), # purchase_date filter
|
||||||
|
*asset_names, # asset names for IN clause
|
||||||
|
filters.get("from_date") # capitalization exclusion
|
||||||
|
]
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns(filters):
|
||||||
|
"""Создает колонки отчета"""
|
||||||
|
columns = []
|
||||||
|
|
||||||
|
# Основные колонки
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": "Əmlak",
|
||||||
|
"fieldname": "asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Asset",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Tarix",
|
||||||
|
"fieldname": "purchase_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# Создаем колонки для каждого tax article
|
||||||
|
tax_exempt_articles = get_tax_exempt_articles_list()
|
||||||
|
|
||||||
|
for article in tax_exempt_articles:
|
||||||
|
article_key = get_field_key(article)
|
||||||
|
|
||||||
|
# Сокращенное название для заголовка колонки
|
||||||
|
short_name = get_short_article_name(article)
|
||||||
|
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.day_before_from_date) + " əsasən",
|
||||||
|
"fieldname": f"{article_key}_value_from",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.to_date) + " əsasən",
|
||||||
|
"fieldname": f"{article_key}_value_to",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Sığorta dəyəri",
|
||||||
|
"fieldname": f"{article_key}_insured",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
||||||
|
def get_short_article_name(tax_article):
|
||||||
|
"""Создает короткое название для заголовка колонки"""
|
||||||
|
if "199.1-ci" in tax_article and "azaldılmalı" in tax_article:
|
||||||
|
return "199.1 (Azaldılmalı)"
|
||||||
|
elif "199.4.1-1-ci" in tax_article:
|
||||||
|
return "199.4.1-1"
|
||||||
|
elif "199.4.1-ci" in tax_article:
|
||||||
|
return "199.4.1"
|
||||||
|
elif "199.4.2-ci" in tax_article:
|
||||||
|
return "199.4.2"
|
||||||
|
elif "199.4.3-cü" in tax_article:
|
||||||
|
return "199.4.3"
|
||||||
|
elif "199.4.4-cü" in tax_article:
|
||||||
|
return "199.4.4"
|
||||||
|
elif "199.5-ci" in tax_article:
|
||||||
|
return "199.5"
|
||||||
|
elif "199.7-ci" in tax_article:
|
||||||
|
return "199.7"
|
||||||
|
elif "199.8-ci" in tax_article:
|
||||||
|
return "199.8"
|
||||||
|
elif "199.9-cu" in tax_article:
|
||||||
|
return "199.9"
|
||||||
|
elif "199.11-ci" in tax_article:
|
||||||
|
return "199.11"
|
||||||
|
elif "199.14-cü" in tax_article:
|
||||||
|
return "199.14"
|
||||||
|
elif "199.15-ci" in tax_article:
|
||||||
|
return "199.15"
|
||||||
|
elif "199.16-cı" in tax_article:
|
||||||
|
return "199.16"
|
||||||
|
elif "199.17-ci" in tax_article:
|
||||||
|
return "199.17"
|
||||||
|
elif "199.18-ci" in tax_article:
|
||||||
|
return "199.18"
|
||||||
|
elif "199.19-cu" in tax_article:
|
||||||
|
return "199.19"
|
||||||
|
elif "199.20-ci" in tax_article:
|
||||||
|
return "199.20"
|
||||||
|
elif "227.1-ci" in tax_article:
|
||||||
|
return "227.1"
|
||||||
|
elif "pay bölgüsü" in tax_article:
|
||||||
|
return "Pay Bölgüsü"
|
||||||
|
elif "iqtisadi zonalar" in tax_article:
|
||||||
|
return "İqtisadi Zonalar"
|
||||||
|
elif "beynəlxalq müqavilələr" in tax_article:
|
||||||
|
return "Beynəlxalq"
|
||||||
|
else:
|
||||||
|
return "Digər"
|
||||||
|
|
@ -0,0 +1,381 @@
|
||||||
|
// Copyright (c) 2024, Your Company and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.query_reports["Taxable Assets Establishment Year Report"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatter": function (value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
// Подсветка колонок с остатками и страховкой
|
||||||
|
if (column.fieldname && column.fieldname.includes("value_")) {
|
||||||
|
if (value && parseFloat(value) > 0) {
|
||||||
|
// Разные цвета для разных типов колонок - более яркие для establishment year
|
||||||
|
let color = "#28a745"; // зеленый по умолчанию
|
||||||
|
|
||||||
|
if (column.fieldname.includes("_value_from")) {
|
||||||
|
color = "#007bff"; // синий для начальных остатков (ярче)
|
||||||
|
} else if (column.fieldname.includes("_value_to")) {
|
||||||
|
color = "#28a745"; // зеленый для конечных остатков
|
||||||
|
} else if (column.fieldname.includes("_insured")) {
|
||||||
|
color = "#fd7e14"; // оранжевый для страховки (ярче)
|
||||||
|
}
|
||||||
|
|
||||||
|
value = `<span style="color: ${color}; font-weight: bold; background-color: ${color}20; padding: 3px 8px; border-radius: 4px; border-left: 3px solid ${color};">${value}</span>`;
|
||||||
|
} else if (value == 0 || !value) {
|
||||||
|
value = `<span style="color: #ccc;">0.00</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Asset колонки - специальная для establishment year
|
||||||
|
if (column.fieldname == "asset" && value) {
|
||||||
|
value = `<span style="color: #dc3545; font-weight: bold; background-color: #dc354515; padding: 2px 6px; border-radius: 3px;">🏢 ${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Date колонки
|
||||||
|
if (column.fieldname == "purchase_date" && value) {
|
||||||
|
value = `<span style="color: #6f42c1; font-weight: 600;">📅 ${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
"onload": function(report) {
|
||||||
|
// Добавляем кастомные кнопки
|
||||||
|
report.page.add_inner_button(__("Export Establishment Year Summary"), function() {
|
||||||
|
export_establishment_year_summary(report);
|
||||||
|
});
|
||||||
|
|
||||||
|
report.page.add_inner_button(__("Show Asset Types"), function() {
|
||||||
|
show_asset_types_info();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем информационное сообщение
|
||||||
|
report.page.add_inner_button(__("About This Report"), function() {
|
||||||
|
show_report_info(report);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"after_datatable_render": function(datatable_obj) {
|
||||||
|
// Добавляем итоговую статистику
|
||||||
|
setTimeout(() => {
|
||||||
|
add_establishment_year_statistics(datatable_obj);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Функция показа информации об отчете
|
||||||
|
function show_report_info(report) {
|
||||||
|
let company = report.filters.find(f => f.fieldname === 'company').value;
|
||||||
|
|
||||||
|
if (company) {
|
||||||
|
frappe.call({
|
||||||
|
method: 'frappe.client.get_value',
|
||||||
|
args: {
|
||||||
|
doctype: 'Company',
|
||||||
|
fieldname: 'date_of_establishment',
|
||||||
|
filters: {name: company}
|
||||||
|
},
|
||||||
|
callback: function(r) {
|
||||||
|
let establishment_date = r.message ? r.message.date_of_establishment : 'N/A';
|
||||||
|
let establishment_year = establishment_date !== 'N/A' ? new Date(establishment_date).getFullYear() : 'N/A';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Establishment Year Report Information"),
|
||||||
|
message: `
|
||||||
|
<div style="padding: 15px;">
|
||||||
|
<h4 style="color: #dc3545; margin-bottom: 15px;">📋 Vergiyə cəlb olunan əsas vəsaitlər - Təsis ili</h4>
|
||||||
|
<hr>
|
||||||
|
<p><strong>Şirkət:</strong> ${company}</p>
|
||||||
|
<p><strong>Təsis tarixi:</strong> ${establishment_date}</p>
|
||||||
|
<p><strong>Təsis ili:</strong> ${establishment_year}</p>
|
||||||
|
<hr>
|
||||||
|
<p style="color: #6c757d; margin-bottom: 10px;">
|
||||||
|
<strong>Bu hesabat göstərir:</strong><br>
|
||||||
|
• Yalnız şirkətin təsis ilində alınmış aktivləri<br>
|
||||||
|
• Vergiyə cəlb olunan əsas vəsaitlər tipində olanları<br>
|
||||||
|
• Seçilmiş dövr üzrə qalıqlar və sığorta dəyəri
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
frappe.msgprint(__('Please select a company first'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция экспорта сводки по типам активов года создания
|
||||||
|
function export_establishment_year_summary(report) {
|
||||||
|
let data = report.data;
|
||||||
|
let summary = calculate_asset_type_totals(data);
|
||||||
|
|
||||||
|
// Создаем CSV с итогами по типам активов года создания
|
||||||
|
let csv_content = "Asset Type (Establishment Year),Assets Count,Total Value From,Total Value To,Total Insured Value\n";
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
csv_content += `"${item.asset_type}",${item.assets_count},${item.total_value_from},${item.total_value_to},${item.total_insured}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
csv_content += `\n"TOTAL (ESTABLISHMENT YEAR)",${totals.total_assets},${totals.total_value_from},${totals.total_value_to},${totals.total_insured}\n`;
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'taxable_assets_establishment_year_' + frappe.datetime.get_today() + '.csv';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
frappe.show_alert({message: __("Establishment year summary exported successfully"), indicator: "green"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция расчета итогов по типам активов
|
||||||
|
function calculate_asset_type_totals(data) {
|
||||||
|
let asset_types = get_asset_types_list();
|
||||||
|
let summary = [];
|
||||||
|
|
||||||
|
asset_types.forEach(asset_type => {
|
||||||
|
let asset_type_key = get_field_key_js(asset_type.full_name);
|
||||||
|
let assets_count = 0;
|
||||||
|
let total_value_from = 0;
|
||||||
|
let total_value_to = 0;
|
||||||
|
let total_insured = 0;
|
||||||
|
|
||||||
|
data.forEach(row => {
|
||||||
|
let value_from = row[`${asset_type_key}_value_from`] || 0;
|
||||||
|
let value_to = row[`${asset_type_key}_value_to`] || 0;
|
||||||
|
let insured = row[`${asset_type_key}_insured`] || 0;
|
||||||
|
|
||||||
|
if (value_from > 0 || value_to > 0 || insured > 0) {
|
||||||
|
assets_count++;
|
||||||
|
total_value_from += value_from;
|
||||||
|
total_value_to += value_to;
|
||||||
|
total_insured += insured;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assets_count > 0) {
|
||||||
|
summary.push({
|
||||||
|
asset_type: asset_type.short_name,
|
||||||
|
assets_count: assets_count,
|
||||||
|
total_value_from: total_value_from,
|
||||||
|
total_value_to: total_value_to,
|
||||||
|
total_insured: total_insured
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция показа информации о типах активов
|
||||||
|
function show_asset_types_info() {
|
||||||
|
let asset_types = get_asset_types_list();
|
||||||
|
let info_html = '<div class="asset-types-info">';
|
||||||
|
info_html += '<h4>🏢 Təsis ilində alınmış vergiyə cəlb olunan əsas vəsaitlər:</h4>';
|
||||||
|
info_html += '<div class="row">';
|
||||||
|
|
||||||
|
asset_types.forEach((asset_type, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
info_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
info_html += '<div class="col-md-6" style="margin-bottom: 8px;">';
|
||||||
|
info_html += `<strong>${asset_type.short_name}:</strong><br>`;
|
||||||
|
info_html += `<small style="color: #6c757d;">${asset_type.full_name}</small>`;
|
||||||
|
info_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
info_html += '</div></div>';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Asset Types Information"),
|
||||||
|
message: info_html,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция добавления статистики под таблицу
|
||||||
|
function add_establishment_year_statistics(datatable_obj) {
|
||||||
|
if (datatable_obj && datatable_obj.data) {
|
||||||
|
let summary = calculate_asset_type_totals(datatable_obj.data);
|
||||||
|
|
||||||
|
let stats_html = '<div class="establishment-year-statistics" style="margin-top: 20px; padding: 20px; background: linear-gradient(135deg, #fff5f5 0%, #fff 100%); border-radius: 8px; border: 2px solid #dc3545; box-shadow: 0 2px 8px rgba(220,53,69,0.1);">';
|
||||||
|
stats_html += '<h4 style="margin-bottom: 15px; color: #dc3545; display: flex; align-items: center;"><span style="margin-right: 8px;">🏢</span> Təsis ili üzrə vergiyə cəlb olunan əsas vəsaitlər:</h4>';
|
||||||
|
|
||||||
|
// Группируем по типам активов
|
||||||
|
let grouped_summary = group_summary_by_asset_category(summary);
|
||||||
|
|
||||||
|
Object.keys(grouped_summary).forEach(group_name => {
|
||||||
|
stats_html += `<h5 style="margin-top: 15px; margin-bottom: 10px; color: #6f42c1;">${group_name}</h5>`;
|
||||||
|
stats_html += '<div class="row">';
|
||||||
|
|
||||||
|
grouped_summary[group_name].forEach((item, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
stats_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
stats_html += '<div class="col-md-6" style="margin-bottom: 10px;">';
|
||||||
|
stats_html += `<div style="padding: 12px; border: 2px solid #e9ecef; border-left: 4px solid #dc3545; border-radius: 6px; background: white; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">`;
|
||||||
|
stats_html += `<strong style="color: #dc3545;">${item.asset_type}</strong><br>`;
|
||||||
|
stats_html += `<small style="color: #6c757d;">Aktivlər: <strong>${item.assets_count}</strong> | Başlanğıc: <strong>${item.total_value_from.toFixed(2)}</strong> | Son: <strong>${item.total_value_to.toFixed(2)}</strong> | Sığorta: <strong>${item.total_insured.toFixed(2)}</strong></small>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
stats_html += `<div style="margin-top: 20px; padding: 15px; border-top: 3px solid #dc3545; background: linear-gradient(135deg, #dc354510 0%, #fff 100%);">`;
|
||||||
|
stats_html += `<div class="row text-center">`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #dc3545; font-size: 14px; font-weight: bold;">📊 Cəmi aktivlər<br><span style="font-size: 18px;">${totals.total_assets}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #007bff; font-size: 14px; font-weight: bold;">💰 Başlanğıc qalıq<br><span style="font-size: 18px;">${totals.total_value_from.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #28a745; font-size: 14px; font-weight: bold;">💎 Son qalıq<br><span style="font-size: 18px;">${totals.total_value_to.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><span style="color: #fd7e14; font-size: 14px; font-weight: bold;">🛡️ Ümumi sığorta<br><span style="font-size: 18px;">${totals.total_insured.toFixed(2)}</span></span></div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
|
||||||
|
// Удаляем предыдущую статистику если есть
|
||||||
|
$('.establishment-year-statistics').remove();
|
||||||
|
|
||||||
|
// Добавляем новую статистику
|
||||||
|
$(stats_html).insertAfter('.datatable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группировка активов по категориям
|
||||||
|
function group_summary_by_asset_category(summary) {
|
||||||
|
let grouped = {
|
||||||
|
'Binalar və tikililər': [],
|
||||||
|
'Yaşayış sahələri': [],
|
||||||
|
'Qeyri-yaşayış sahələri': [],
|
||||||
|
'Maşın və avadanlıqlar': [],
|
||||||
|
'Nəqliyyat və texnika': [],
|
||||||
|
'Digər aktivlər': []
|
||||||
|
};
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
if (item.asset_type.includes('Binalar') || item.asset_type.includes('Qurğular')) {
|
||||||
|
grouped['Binalar və tikililər'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Yaşayış') || item.asset_type.includes('Mənzillər')) {
|
||||||
|
grouped['Yaşayış sahələri'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Qeyri-yaşayış') || item.asset_type.includes('Kompleks')) {
|
||||||
|
grouped['Qeyri-yaşayış sahələri'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Maşın') || item.asset_type.includes('Texnologiya')) {
|
||||||
|
grouped['Maşın və avadanlıqlar'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Nəqliyyat')) {
|
||||||
|
grouped['Nəqliyyat və texnika'].push(item);
|
||||||
|
} else {
|
||||||
|
grouped['Digər aktivlər'].push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Удаляем пустые группы
|
||||||
|
Object.keys(grouped).forEach(key => {
|
||||||
|
if (grouped[key].length === 0) {
|
||||||
|
delete grouped[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return grouped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательные функции
|
||||||
|
|
||||||
|
function get_asset_types_list() {
|
||||||
|
return [
|
||||||
|
{short_name: "Binalar və Qurğular", full_name: "Binalar, tikililər və qurğular"},
|
||||||
|
{short_name: "Çoxmərtəbəli Binaları", full_name: "Çoxmərtəbəli (çoxmənzilli) yaşayış binalar"},
|
||||||
|
{short_name: "Qeyri-yaşayış Binaları", full_name: "Qeyri-yaşayış binaları (sahələri)"},
|
||||||
|
{short_name: "Əmlak Kompleksləri", full_name: "Əmlak kompleksi kimi müəssisələr"},
|
||||||
|
{short_name: "Qurğular", full_name: "Qurğular"},
|
||||||
|
{short_name: "Mənzillər", full_name: "Mənzillər"},
|
||||||
|
{short_name: "Fərdi Yaşayış Evləri", full_name: "Fərdi yaşayış və bağ evləri"},
|
||||||
|
{short_name: "Maşın və Avadanlıqlar", full_name: "Maşınlar və avadanlıqlar"},
|
||||||
|
{short_name: "Yüksək Texnologiyalar", full_name: "Yüksək texnologiyalar məhsulu olan hesablama texnikası"},
|
||||||
|
{short_name: "Nəqliyyat Vasitələri", full_name: "Nəqliyyat vasitələri"},
|
||||||
|
{short_name: "Digər Əsas Vəsaitlər", full_name: "Digər əsas vəsaitlər"}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_field_key_js(asset_type) {
|
||||||
|
// Дублируем логику из Python для создания ключей полей
|
||||||
|
if (!asset_type) {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset_type.includes("Binalar, tikililər və qurğular")) {
|
||||||
|
return "buildings_structures_facilities";
|
||||||
|
} else if (asset_type.includes("Çoxmərtəbəli") && asset_type.includes("yaşayış binalar")) {
|
||||||
|
return "multi_story_residential";
|
||||||
|
} else if (asset_type.includes("Qeyri-yaşayış binaları")) {
|
||||||
|
return "non_residential_buildings";
|
||||||
|
} else if (asset_type.includes("Əmlak kompleksi kimi müəssisələr")) {
|
||||||
|
return "property_complex_enterprises";
|
||||||
|
} else if (asset_type === "Qurğular") {
|
||||||
|
return "installations";
|
||||||
|
} else if (asset_type.includes("Mənzillər")) {
|
||||||
|
return "apartments";
|
||||||
|
} else if (asset_type.includes("Fərdi yaşayış və bağ evləri")) {
|
||||||
|
return "individual_residential_garden";
|
||||||
|
} else if (asset_type.includes("Maşınlar və avadanlıqlar")) {
|
||||||
|
return "machinery_equipment";
|
||||||
|
} else if (asset_type.includes("Yüksək texnologiyalar") && asset_type.includes("hesablama texnikası")) {
|
||||||
|
return "high_tech_computing";
|
||||||
|
} else if (asset_type.includes("Nəqliyyat vasitələri")) {
|
||||||
|
return "transport_vehicles";
|
||||||
|
} else if (asset_type.includes("Digər əsas vəsaitlər")) {
|
||||||
|
return "other_fixed_assets";
|
||||||
|
} else {
|
||||||
|
return "other_asset_type";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2025-09-18 14:44:44.655925",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letterhead": null,
|
||||||
|
"modified": "2025-09-18 14:44:44.655925",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Taxes Az",
|
||||||
|
"name": "Taxable Assets Establishment Year Report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Asset",
|
||||||
|
"report_name": "Taxable Assets Establishment Year Report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Quality Manager"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,372 @@
|
||||||
|
# Copyright (c) 2024, Your Company and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import add_days, flt, formatdate
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
filters.day_before_from_date = add_days(filters.from_date, -1)
|
||||||
|
columns, data = get_columns(filters), get_data(filters)
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
"""Получаем данные по налогооблагаемым активам года создания компании"""
|
||||||
|
|
||||||
|
# Список всех типов taxable assets
|
||||||
|
taxable_asset_types = get_taxable_asset_types_list()
|
||||||
|
|
||||||
|
# Получаем активы с этими типами (только год создания компании)
|
||||||
|
assets_data = get_establishment_year_taxable_assets(filters, taxable_asset_types)
|
||||||
|
|
||||||
|
if not assets_data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Получаем расчеты остатков для этих активов
|
||||||
|
asset_balances = get_asset_balances(filters, [asset['name'] for asset in assets_data])
|
||||||
|
|
||||||
|
# Формируем итоговые данные
|
||||||
|
data = []
|
||||||
|
|
||||||
|
for asset in assets_data:
|
||||||
|
row = frappe._dict()
|
||||||
|
|
||||||
|
# Основные данные актива
|
||||||
|
row.asset = asset['name']
|
||||||
|
row.purchase_date = asset['purchase_date']
|
||||||
|
row.taxable_asset_type = asset['taxable_asset_type']
|
||||||
|
row.insured_value = flt(asset.get('insured_value', 0))
|
||||||
|
|
||||||
|
# Находим баланс для этого актива
|
||||||
|
asset_balance = next((bal for bal in asset_balances if bal['asset'] == asset['name']), {})
|
||||||
|
|
||||||
|
# Рассчитываем остатки на начало и конец периода
|
||||||
|
value_as_on_from_date = flt(asset_balance.get('value_as_on_from_date', 0))
|
||||||
|
value_of_new_purchase = flt(asset_balance.get('value_of_new_purchase', 0))
|
||||||
|
value_of_sold_asset = flt(asset_balance.get('value_of_sold_asset', 0))
|
||||||
|
value_of_scrapped_asset = flt(asset_balance.get('value_of_scrapped_asset', 0))
|
||||||
|
value_of_capitalized_asset = flt(asset_balance.get('value_of_capitalized_asset', 0))
|
||||||
|
|
||||||
|
value_as_on_to_date = (
|
||||||
|
value_as_on_from_date +
|
||||||
|
value_of_new_purchase -
|
||||||
|
value_of_sold_asset -
|
||||||
|
value_of_scrapped_asset -
|
||||||
|
value_of_capitalized_asset
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализируем все колонки нулями
|
||||||
|
for asset_type in taxable_asset_types:
|
||||||
|
asset_type_key = get_field_key(asset_type)
|
||||||
|
row[f"{asset_type_key}_value_from"] = 0
|
||||||
|
row[f"{asset_type_key}_value_to"] = 0
|
||||||
|
row[f"{asset_type_key}_insured"] = 0
|
||||||
|
|
||||||
|
# Заполняем колонки для соответствующего типа актива
|
||||||
|
if asset['taxable_asset_type']:
|
||||||
|
asset_type_key = get_field_key(asset['taxable_asset_type'])
|
||||||
|
row[f"{asset_type_key}_value_from"] = value_as_on_from_date
|
||||||
|
row[f"{asset_type_key}_value_to"] = value_as_on_to_date
|
||||||
|
row[f"{asset_type_key}_insured"] = row.insured_value
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_taxable_asset_types_list():
|
||||||
|
"""Возвращает список всех типов taxable assets"""
|
||||||
|
return [
|
||||||
|
"Binalar, tikililər və qurğular",
|
||||||
|
"Çoxmərtəbəli (çoxmənzilli) yaşayış binalar",
|
||||||
|
"Qeyri-yaşayış binaları (sahələri)",
|
||||||
|
"Əmlak kompleksi kimi müəssisələr",
|
||||||
|
"Qurğular",
|
||||||
|
"Mənzillər",
|
||||||
|
"Fərdi yaşayış və bağ evləri",
|
||||||
|
"Maşınlar və avadanlıqlar",
|
||||||
|
"Yüksək texnologiyalar məhsulu olan hesablama texnikası",
|
||||||
|
"Nəqliyyat vasitələri",
|
||||||
|
"Digər əsas vəsaitlər"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_field_key(asset_type):
|
||||||
|
"""Создает ключ поля на основе типа актива"""
|
||||||
|
if not asset_type:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
# Создаем ключи для каждого типа актива
|
||||||
|
if "Binalar, tikililər və qurğular" in asset_type:
|
||||||
|
return "buildings_structures_facilities"
|
||||||
|
elif "Çoxmərtəbəli" in asset_type and "yaşayış binalar" in asset_type:
|
||||||
|
return "multi_story_residential"
|
||||||
|
elif "Qeyri-yaşayış binaları" in asset_type:
|
||||||
|
return "non_residential_buildings"
|
||||||
|
elif "Əmlak kompleksi kimi müəssisələr" in asset_type:
|
||||||
|
return "property_complex_enterprises"
|
||||||
|
elif "Qurğular" == asset_type:
|
||||||
|
return "installations"
|
||||||
|
elif "Mənzillər" in asset_type:
|
||||||
|
return "apartments"
|
||||||
|
elif "Fərdi yaşayış və bağ evləri" in asset_type:
|
||||||
|
return "individual_residential_garden"
|
||||||
|
elif "Maşınlar və avadanlıqlar" in asset_type:
|
||||||
|
return "machinery_equipment"
|
||||||
|
elif "Yüksək texnologiyalar" in asset_type and "hesablama texnikası" in asset_type:
|
||||||
|
return "high_tech_computing"
|
||||||
|
elif "Nəqliyyat vasitələri" in asset_type:
|
||||||
|
return "transport_vehicles"
|
||||||
|
elif "Digər əsas vəsaitlər" in asset_type:
|
||||||
|
return "other_fixed_assets"
|
||||||
|
else:
|
||||||
|
return "other_asset_type"
|
||||||
|
|
||||||
|
|
||||||
|
def get_establishment_year_taxable_assets(filters, taxable_asset_types):
|
||||||
|
"""Получает активы с типом 'Vergiyə cəlb olunan əsas vəsaitlər' ТОЛЬКО года создания компании"""
|
||||||
|
|
||||||
|
conditions = []
|
||||||
|
values = []
|
||||||
|
|
||||||
|
# Фильтр по компании
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions.append("a.company = %s")
|
||||||
|
values.append(filters.get("company"))
|
||||||
|
|
||||||
|
# Фильтр по датам
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions.append("a.purchase_date <= %s")
|
||||||
|
values.append(filters.get("to_date"))
|
||||||
|
|
||||||
|
# Фильтр по asset type
|
||||||
|
conditions.append("a.custom_asset_type = %s")
|
||||||
|
values.append("Vergiyə cəlb olunan əsas vəsaitlər")
|
||||||
|
|
||||||
|
# Фильтр по taxable asset types
|
||||||
|
asset_type_placeholders = ", ".join(["%s"] * len(taxable_asset_types))
|
||||||
|
conditions.append(f"a.taxable_asset_type IN ({asset_type_placeholders})")
|
||||||
|
values.extend(taxable_asset_types)
|
||||||
|
|
||||||
|
# Только подтвержденные активы
|
||||||
|
conditions.append("a.docstatus = 1")
|
||||||
|
|
||||||
|
# ТОЛЬКО активы года создания компании
|
||||||
|
conditions.append("YEAR(a.purchase_date) = YEAR(c.date_of_establishment)")
|
||||||
|
|
||||||
|
where_clause = ""
|
||||||
|
if conditions:
|
||||||
|
where_clause = "WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
# Исключаем капитализированные активы (как в стандартном отчете)
|
||||||
|
exclude_capitalized = """
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
where_clause += exclude_capitalized
|
||||||
|
values.append(filters.get("from_date"))
|
||||||
|
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name,
|
||||||
|
a.purchase_date,
|
||||||
|
a.taxable_asset_type,
|
||||||
|
a.insured_value
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
JOIN
|
||||||
|
`tabCompany` c ON a.company = c.name
|
||||||
|
{where_clause}
|
||||||
|
ORDER BY
|
||||||
|
a.purchase_date DESC, a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_balances(filters, asset_names):
|
||||||
|
"""Рассчитывает остатки активов на основе стандартной логики"""
|
||||||
|
|
||||||
|
if not asset_names:
|
||||||
|
return []
|
||||||
|
|
||||||
|
asset_placeholders = ", ".join(["%s"] * len(asset_names))
|
||||||
|
|
||||||
|
# Используем ту же логику что в стандартном отчете для расчета остатков
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name as asset,
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date < %s THEN
|
||||||
|
CASE WHEN IFNULL(a.disposal_date, 0) = 0 OR a.disposal_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_as_on_from_date,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_new_purchase,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Sold" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_sold_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Scrapped" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_scrapped_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Capitalized" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_capitalized_asset
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
WHERE
|
||||||
|
a.docstatus = 1
|
||||||
|
AND a.company = %s
|
||||||
|
AND a.purchase_date <= %s
|
||||||
|
AND a.name IN ({asset_placeholders})
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
GROUP BY a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = [
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 1
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 2
|
||||||
|
filters.get("from_date"), # value_of_new_purchase
|
||||||
|
filters.get("from_date"), # value_of_sold_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_sold_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_scrapped_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_scrapped_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_capitalized_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_capitalized_asset condition 2
|
||||||
|
filters.get("company"), # company filter
|
||||||
|
filters.get("to_date"), # purchase_date filter
|
||||||
|
*asset_names, # asset names for IN clause
|
||||||
|
filters.get("from_date") # capitalization exclusion
|
||||||
|
]
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns(filters):
|
||||||
|
"""Создает колонки отчета"""
|
||||||
|
columns = []
|
||||||
|
|
||||||
|
# Основные колонки
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": "Əmlak",
|
||||||
|
"fieldname": "asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Asset",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Tarix",
|
||||||
|
"fieldname": "purchase_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# Создаем колонки для каждого типа taxable asset
|
||||||
|
taxable_asset_types = get_taxable_asset_types_list()
|
||||||
|
|
||||||
|
for asset_type in taxable_asset_types:
|
||||||
|
asset_type_key = get_field_key(asset_type)
|
||||||
|
|
||||||
|
# Сокращенное название для заголовка колонки
|
||||||
|
short_name = get_short_asset_type_name(asset_type)
|
||||||
|
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.day_before_from_date) + " əsasən",
|
||||||
|
"fieldname": f"{asset_type_key}_value_from",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.to_date) + " əsasən",
|
||||||
|
"fieldname": f"{asset_type_key}_value_to",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Sığorta dəyəri",
|
||||||
|
"fieldname": f"{asset_type_key}_insured",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
||||||
|
def get_short_asset_type_name(asset_type):
|
||||||
|
"""Создает короткое название для заголовка колонки"""
|
||||||
|
if "Binalar, tikililər və qurğular" in asset_type:
|
||||||
|
return "Binalar və Qurğular"
|
||||||
|
elif "Çoxmərtəbəli" in asset_type and "yaşayış binalar" in asset_type:
|
||||||
|
return "Çoxmərtəbəli Binaları"
|
||||||
|
elif "Qeyri-yaşayış binaları" in asset_type:
|
||||||
|
return "Qeyri-yaşayış Binaları"
|
||||||
|
elif "Əmlak kompleksi kimi müəssisələr" in asset_type:
|
||||||
|
return "Əmlak Kompleksləri"
|
||||||
|
elif "Qurğular" == asset_type:
|
||||||
|
return "Qurğular"
|
||||||
|
elif "Mənzillər" in asset_type:
|
||||||
|
return "Mənzillər"
|
||||||
|
elif "Fərdi yaşayış və bağ evləri" in asset_type:
|
||||||
|
return "Fərdi Yaşayış Evləri"
|
||||||
|
elif "Maşınlar və avadanlıqlar" in asset_type:
|
||||||
|
return "Maşın və Avadanlıqlar"
|
||||||
|
elif "Yüksək texnologiyalar" in asset_type and "hesablama texnikası" in asset_type:
|
||||||
|
return "Yüksək Texnologiyalar"
|
||||||
|
elif "Nəqliyyat vasitələri" in asset_type:
|
||||||
|
return "Nəqliyyat Vasitələri"
|
||||||
|
elif "Digər əsas vəsaitlər" in asset_type:
|
||||||
|
return "Digər Əsas Vəsaitlər"
|
||||||
|
else:
|
||||||
|
return "Digər"
|
||||||
|
|
@ -0,0 +1,333 @@
|
||||||
|
// Copyright (c) 2024, Your Company and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.query_reports["Taxable Assets Report"] = {
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"fieldname": "company",
|
||||||
|
"label": __("Company"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Company",
|
||||||
|
"default": frappe.defaults.get_user_default("Company"),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_date",
|
||||||
|
"label": __("From Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||||
|
"reqd": 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "to_date",
|
||||||
|
"label": __("To Date"),
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"default": frappe.datetime.get_today(),
|
||||||
|
"reqd": 1,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatter": function (value, row, column, data, default_formatter) {
|
||||||
|
value = default_formatter(value, row, column, data);
|
||||||
|
|
||||||
|
// Подсветка колонок с остатками и страховкой
|
||||||
|
if (column.fieldname && column.fieldname.includes("value_")) {
|
||||||
|
if (value && parseFloat(value) > 0) {
|
||||||
|
// Разные цвета для разных типов колонок
|
||||||
|
let color = "#28a745"; // зеленый по умолчанию
|
||||||
|
|
||||||
|
if (column.fieldname.includes("_value_from")) {
|
||||||
|
color = "#17a2b8"; // голубой для начальных остатков
|
||||||
|
} else if (column.fieldname.includes("_value_to")) {
|
||||||
|
color = "#28a745"; // зеленый для конечных остатков
|
||||||
|
} else if (column.fieldname.includes("_insured")) {
|
||||||
|
color = "#ffc107"; // желтый для страховки
|
||||||
|
}
|
||||||
|
|
||||||
|
value = `<span style="color: ${color}; font-weight: bold; background-color: ${color}15; padding: 2px 6px; border-radius: 3px;">${value}</span>`;
|
||||||
|
} else if (value == 0 || !value) {
|
||||||
|
value = `<span style="color: #ccc;">0.00</span>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Asset колонки
|
||||||
|
if (column.fieldname == "asset" && value) {
|
||||||
|
value = `<span style="color: #007bff; font-weight: bold;">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Подсветка Date колонки
|
||||||
|
if (column.fieldname == "purchase_date" && value) {
|
||||||
|
value = `<span style="color: #6c757d; font-weight: 500;">${value}</span>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
"onload": function(report) {
|
||||||
|
// Добавляем кастомные кнопки
|
||||||
|
report.page.add_inner_button(__("Export Asset Type Summary"), function() {
|
||||||
|
export_asset_type_summary(report);
|
||||||
|
});
|
||||||
|
|
||||||
|
report.page.add_inner_button(__("Show Asset Types"), function() {
|
||||||
|
show_asset_types_info();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"after_datatable_render": function(datatable_obj) {
|
||||||
|
// Добавляем итоговую статистику
|
||||||
|
setTimeout(() => {
|
||||||
|
add_asset_type_statistics(datatable_obj);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Функция экспорта сводки по типам активов
|
||||||
|
function export_asset_type_summary(report) {
|
||||||
|
let data = report.data;
|
||||||
|
let summary = calculate_asset_type_totals(data);
|
||||||
|
|
||||||
|
// Создаем CSV с итогами по типам активов
|
||||||
|
let csv_content = "Asset Type,Assets Count,Total Value From,Total Value To,Total Insured Value\n";
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
csv_content += `"${item.asset_type}",${item.assets_count},${item.total_value_from},${item.total_value_to},${item.total_insured}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Добавляем общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
csv_content += `\n"TOTAL",${totals.total_assets},${totals.total_value_from},${totals.total_value_to},${totals.total_insured}\n`;
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
let blob = new Blob([csv_content], { type: 'text/csv;charset=utf-8' });
|
||||||
|
let url = window.URL.createObjectURL(blob);
|
||||||
|
let a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'taxable_assets_summary_' + frappe.datetime.get_today() + '.csv';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
window.URL.revokeObjectURL(url);
|
||||||
|
|
||||||
|
frappe.show_alert({message: __("Asset type summary exported successfully"), indicator: "green"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция расчета итогов по типам активов
|
||||||
|
function calculate_asset_type_totals(data) {
|
||||||
|
let asset_types = get_asset_types_list();
|
||||||
|
let summary = [];
|
||||||
|
|
||||||
|
asset_types.forEach(asset_type => {
|
||||||
|
let asset_type_key = get_field_key_js(asset_type.full_name);
|
||||||
|
let assets_count = 0;
|
||||||
|
let total_value_from = 0;
|
||||||
|
let total_value_to = 0;
|
||||||
|
let total_insured = 0;
|
||||||
|
|
||||||
|
data.forEach(row => {
|
||||||
|
let value_from = row[`${asset_type_key}_value_from`] || 0;
|
||||||
|
let value_to = row[`${asset_type_key}_value_to`] || 0;
|
||||||
|
let insured = row[`${asset_type_key}_insured`] || 0;
|
||||||
|
|
||||||
|
if (value_from > 0 || value_to > 0 || insured > 0) {
|
||||||
|
assets_count++;
|
||||||
|
total_value_from += value_from;
|
||||||
|
total_value_to += value_to;
|
||||||
|
total_insured += insured;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assets_count > 0) {
|
||||||
|
summary.push({
|
||||||
|
asset_type: asset_type.short_name,
|
||||||
|
assets_count: assets_count,
|
||||||
|
total_value_from: total_value_from,
|
||||||
|
total_value_to: total_value_to,
|
||||||
|
total_insured: total_insured
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция показа информации о типах активов
|
||||||
|
function show_asset_types_info() {
|
||||||
|
let asset_types = get_asset_types_list();
|
||||||
|
let info_html = '<div class="asset-types-info">';
|
||||||
|
info_html += '<h4>📋 Типы налогооблагаемых активов в отчете:</h4>';
|
||||||
|
info_html += '<div class="row">';
|
||||||
|
|
||||||
|
asset_types.forEach((asset_type, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
info_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
info_html += '<div class="col-md-6" style="margin-bottom: 8px;">';
|
||||||
|
info_html += `<strong>${asset_type.short_name}:</strong><br>`;
|
||||||
|
info_html += `<small style="color: #6c757d;">${asset_type.full_name}</small>`;
|
||||||
|
info_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
info_html += '</div></div>';
|
||||||
|
|
||||||
|
frappe.msgprint({
|
||||||
|
title: __("Asset Types Information"),
|
||||||
|
message: info_html,
|
||||||
|
wide: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Функция добавления статистики под таблицу
|
||||||
|
function add_asset_type_statistics(datatable_obj) {
|
||||||
|
if (datatable_obj && datatable_obj.data) {
|
||||||
|
let summary = calculate_asset_type_totals(datatable_obj.data);
|
||||||
|
|
||||||
|
let stats_html = '<div class="asset-type-statistics" style="margin-top: 20px; padding: 20px; background: #f8f9fa; border-radius: 8px; border: 1px solid #dee2e6;">';
|
||||||
|
stats_html += '<h4 style="margin-bottom: 15px; color: #495057;">📊 Сводка по типам налогооблагаемых активов:</h4>';
|
||||||
|
|
||||||
|
// Группируем по типам активов
|
||||||
|
let grouped_summary = group_summary_by_asset_category(summary);
|
||||||
|
|
||||||
|
Object.keys(grouped_summary).forEach(group_name => {
|
||||||
|
stats_html += `<h5 style="margin-top: 15px; margin-bottom: 10px; color: #495057;">${group_name}</h5>`;
|
||||||
|
stats_html += '<div class="row">';
|
||||||
|
|
||||||
|
grouped_summary[group_name].forEach((item, index) => {
|
||||||
|
if (index % 2 === 0 && index > 0) {
|
||||||
|
stats_html += '</div><div class="row">';
|
||||||
|
}
|
||||||
|
|
||||||
|
stats_html += '<div class="col-md-6" style="margin-bottom: 10px;">';
|
||||||
|
stats_html += `<div style="padding: 10px; border: 1px solid #dee2e6; border-radius: 4px; background: white;">`;
|
||||||
|
stats_html += `<strong>${item.asset_type}</strong><br>`;
|
||||||
|
stats_html += `<small>Активов: ${item.assets_count} | От: ${item.total_value_from.toFixed(2)} | До: ${item.total_value_to.toFixed(2)} | Страховка: ${item.total_insured.toFixed(2)}</small>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Общие итоги
|
||||||
|
let totals = summary.reduce((acc, item) => {
|
||||||
|
acc.total_assets += item.assets_count;
|
||||||
|
acc.total_value_from += item.total_value_from;
|
||||||
|
acc.total_value_to += item.total_value_to;
|
||||||
|
acc.total_insured += item.total_insured;
|
||||||
|
return acc;
|
||||||
|
}, {total_assets: 0, total_value_from: 0, total_value_to: 0, total_insured: 0});
|
||||||
|
|
||||||
|
stats_html += `<div style="margin-top: 20px; padding-top: 15px; border-top: 2px solid #007bff;">`;
|
||||||
|
stats_html += `<div class="row">`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Всего активов: ${totals.total_assets}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Остаток на начало: ${totals.total_value_from.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Остаток на конец: ${totals.total_value_to.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `<div class="col-md-3"><strong>Всего страховки: ${totals.total_insured.toFixed(2)}</strong></div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
stats_html += `</div>`;
|
||||||
|
|
||||||
|
stats_html += '</div>';
|
||||||
|
|
||||||
|
// Удаляем предыдущую статистику если есть
|
||||||
|
$('.asset-type-statistics').remove();
|
||||||
|
|
||||||
|
// Добавляем новую статистику
|
||||||
|
$(stats_html).insertAfter('.datatable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Группировка активов по категориям
|
||||||
|
function group_summary_by_asset_category(summary) {
|
||||||
|
let grouped = {
|
||||||
|
'Здания и сооружения': [],
|
||||||
|
'Жилая недвижимость': [],
|
||||||
|
'Нежилая недвижимость': [],
|
||||||
|
'Машины и оборудование': [],
|
||||||
|
'Транспорт и техника': [],
|
||||||
|
'Прочие активы': []
|
||||||
|
};
|
||||||
|
|
||||||
|
summary.forEach(item => {
|
||||||
|
if (item.asset_type.includes('Buildings') || item.asset_type.includes('Installations')) {
|
||||||
|
grouped['Здания и сооружения'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Residential') || item.asset_type.includes('Apartments')) {
|
||||||
|
grouped['Жилая недвижимость'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Non-Residential') || item.asset_type.includes('Property Complex')) {
|
||||||
|
grouped['Нежилая недвижимость'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Machinery') || item.asset_type.includes('High-Tech')) {
|
||||||
|
grouped['Машины и оборудование'].push(item);
|
||||||
|
} else if (item.asset_type.includes('Transport')) {
|
||||||
|
grouped['Транспорт и техника'].push(item);
|
||||||
|
} else {
|
||||||
|
grouped['Прочие активы'].push(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Удаляем пустые группы
|
||||||
|
Object.keys(grouped).forEach(key => {
|
||||||
|
if (grouped[key].length === 0) {
|
||||||
|
delete grouped[key];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return grouped;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательные функции
|
||||||
|
|
||||||
|
function get_asset_types_list() {
|
||||||
|
return [
|
||||||
|
{short_name: "Buildings & Structures", full_name: "Binalar, tikililər və qurğular"},
|
||||||
|
{short_name: "Multi-Story Residential", full_name: "Çoxmərtəbəli (çoxmənzilli) yaşayış binalar"},
|
||||||
|
{short_name: "Non-Residential Buildings", full_name: "Qeyri-yaşayış binaları (sahələri)"},
|
||||||
|
{short_name: "Property Complex Enterprises", full_name: "Əmlak kompleksi kimi müəssisələr"},
|
||||||
|
{short_name: "Installations", full_name: "Qurğular"},
|
||||||
|
{short_name: "Apartments", full_name: "Mənzillər"},
|
||||||
|
{short_name: "Individual Residential", full_name: "Fərdi yaşayış və bağ evləri"},
|
||||||
|
{short_name: "Machinery & Equipment", full_name: "Maşınlar və avadanlıqlar"},
|
||||||
|
{short_name: "High-Tech Computing", full_name: "Yüksək texnologiyalar məhsulu olan hesablama texnikası"},
|
||||||
|
{short_name: "Transport Vehicles", full_name: "Nəqliyyat vasitələri"},
|
||||||
|
{short_name: "Other Fixed Assets", full_name: "Digər əsas vəsaitlər"}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_field_key_js(asset_type) {
|
||||||
|
// Дублируем логику из Python для создания ключей полей
|
||||||
|
if (!asset_type) {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset_type.includes("Binalar, tikililər və qurğular")) {
|
||||||
|
return "buildings_structures_facilities";
|
||||||
|
} else if (asset_type.includes("Çoxmərtəbəli") && asset_type.includes("yaşayış binalar")) {
|
||||||
|
return "multi_story_residential";
|
||||||
|
} else if (asset_type.includes("Qeyri-yaşayış binaları")) {
|
||||||
|
return "non_residential_buildings";
|
||||||
|
} else if (asset_type.includes("Əmlak kompleksi kimi müəssisələr")) {
|
||||||
|
return "property_complex_enterprises";
|
||||||
|
} else if (asset_type === "Qurğular") {
|
||||||
|
return "installations";
|
||||||
|
} else if (asset_type.includes("Mənzillər")) {
|
||||||
|
return "apartments";
|
||||||
|
} else if (asset_type.includes("Fərdi yaşayış və bağ evləri")) {
|
||||||
|
return "individual_residential_garden";
|
||||||
|
} else if (asset_type.includes("Maşınlar və avadanlıqlar")) {
|
||||||
|
return "machinery_equipment";
|
||||||
|
} else if (asset_type.includes("Yüksək texnologiyalar") && asset_type.includes("hesablama texnikası")) {
|
||||||
|
return "high_tech_computing";
|
||||||
|
} else if (asset_type.includes("Nəqliyyat vasitələri")) {
|
||||||
|
return "transport_vehicles";
|
||||||
|
} else if (asset_type.includes("Digər əsas vəsaitlər")) {
|
||||||
|
return "other_fixed_assets";
|
||||||
|
} else {
|
||||||
|
return "other_asset_type";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"add_total_row": 0,
|
||||||
|
"columns": [],
|
||||||
|
"creation": "2025-09-18 13:07:15.070482",
|
||||||
|
"disabled": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Report",
|
||||||
|
"filters": [],
|
||||||
|
"idx": 0,
|
||||||
|
"is_standard": "Yes",
|
||||||
|
"letterhead": null,
|
||||||
|
"modified": "2025-09-18 13:07:15.070482",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Taxes Az",
|
||||||
|
"name": "Taxable Assets Report",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"prepared_report": 0,
|
||||||
|
"ref_doctype": "Asset",
|
||||||
|
"report_name": "Taxable Assets Report",
|
||||||
|
"report_type": "Script Report",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Quality Manager"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"timeout": 0
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,372 @@
|
||||||
|
# Copyright (c) 2024, Your Company and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import add_days, flt, formatdate
|
||||||
|
|
||||||
|
|
||||||
|
def execute(filters=None):
|
||||||
|
filters.day_before_from_date = add_days(filters.from_date, -1)
|
||||||
|
columns, data = get_columns(filters), get_data(filters)
|
||||||
|
return columns, data
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(filters):
|
||||||
|
"""Получаем данные по налогооблагаемым активам"""
|
||||||
|
|
||||||
|
# Список всех типов taxable assets
|
||||||
|
taxable_asset_types = get_taxable_asset_types_list()
|
||||||
|
|
||||||
|
# Получаем активы с этими типами
|
||||||
|
assets_data = get_taxable_assets(filters, taxable_asset_types)
|
||||||
|
|
||||||
|
if not assets_data:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# Получаем расчеты остатков для этих активов
|
||||||
|
asset_balances = get_asset_balances(filters, [asset['name'] for asset in assets_data])
|
||||||
|
|
||||||
|
# Формируем итоговые данные
|
||||||
|
data = []
|
||||||
|
|
||||||
|
for asset in assets_data:
|
||||||
|
row = frappe._dict()
|
||||||
|
|
||||||
|
# Основные данные актива
|
||||||
|
row.asset = asset['name']
|
||||||
|
row.purchase_date = asset['purchase_date']
|
||||||
|
row.taxable_asset_type = asset['taxable_asset_type']
|
||||||
|
row.insured_value = flt(asset.get('insured_value', 0))
|
||||||
|
|
||||||
|
# Находим баланс для этого актива
|
||||||
|
asset_balance = next((bal for bal in asset_balances if bal['asset'] == asset['name']), {})
|
||||||
|
|
||||||
|
# Рассчитываем остатки на начало и конец периода
|
||||||
|
value_as_on_from_date = flt(asset_balance.get('value_as_on_from_date', 0))
|
||||||
|
value_of_new_purchase = flt(asset_balance.get('value_of_new_purchase', 0))
|
||||||
|
value_of_sold_asset = flt(asset_balance.get('value_of_sold_asset', 0))
|
||||||
|
value_of_scrapped_asset = flt(asset_balance.get('value_of_scrapped_asset', 0))
|
||||||
|
value_of_capitalized_asset = flt(asset_balance.get('value_of_capitalized_asset', 0))
|
||||||
|
|
||||||
|
value_as_on_to_date = (
|
||||||
|
value_as_on_from_date +
|
||||||
|
value_of_new_purchase -
|
||||||
|
value_of_sold_asset -
|
||||||
|
value_of_scrapped_asset -
|
||||||
|
value_of_capitalized_asset
|
||||||
|
)
|
||||||
|
|
||||||
|
# Инициализируем все колонки нулями
|
||||||
|
for asset_type in taxable_asset_types:
|
||||||
|
asset_type_key = get_field_key(asset_type)
|
||||||
|
row[f"{asset_type_key}_value_from"] = 0
|
||||||
|
row[f"{asset_type_key}_value_to"] = 0
|
||||||
|
row[f"{asset_type_key}_insured"] = 0
|
||||||
|
|
||||||
|
# Заполняем колонки для соответствующего типа актива
|
||||||
|
if asset['taxable_asset_type']:
|
||||||
|
asset_type_key = get_field_key(asset['taxable_asset_type'])
|
||||||
|
row[f"{asset_type_key}_value_from"] = value_as_on_from_date
|
||||||
|
row[f"{asset_type_key}_value_to"] = value_as_on_to_date
|
||||||
|
row[f"{asset_type_key}_insured"] = row.insured_value
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_taxable_asset_types_list():
|
||||||
|
"""Возвращает список всех типов taxable assets"""
|
||||||
|
return [
|
||||||
|
"Binalar, tikililər və qurğular",
|
||||||
|
"Çoxmərtəbəli (çoxmənzilli) yaşayış binalar",
|
||||||
|
"Qeyri-yaşayış binaları (sahələri)",
|
||||||
|
"Əmlak kompleksi kimi müəssisələr",
|
||||||
|
"Qurğular",
|
||||||
|
"Mənzillər",
|
||||||
|
"Fərdi yaşayış və bağ evləri",
|
||||||
|
"Maşınlar və avadanlıqlar",
|
||||||
|
"Yüksək texnologiyalar məhsulu olan hesablama texnikası",
|
||||||
|
"Nəqliyyat vasitələri",
|
||||||
|
"Digər əsas vəsaitlər"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_field_key(asset_type):
|
||||||
|
"""Создает ключ поля на основе типа актива"""
|
||||||
|
if not asset_type:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
# Создаем ключи для каждого типа актива
|
||||||
|
if "Binalar, tikililər və qurğular" in asset_type:
|
||||||
|
return "buildings_structures_facilities"
|
||||||
|
elif "Çoxmərtəbəli" in asset_type and "yaşayış binalar" in asset_type:
|
||||||
|
return "multi_story_residential"
|
||||||
|
elif "Qeyri-yaşayış binaları" in asset_type:
|
||||||
|
return "non_residential_buildings"
|
||||||
|
elif "Əmlak kompleksi kimi müəssisələr" in asset_type:
|
||||||
|
return "property_complex_enterprises"
|
||||||
|
elif "Qurğular" == asset_type:
|
||||||
|
return "installations"
|
||||||
|
elif "Mənzillər" in asset_type:
|
||||||
|
return "apartments"
|
||||||
|
elif "Fərdi yaşayış və bağ evləri" in asset_type:
|
||||||
|
return "individual_residential_garden"
|
||||||
|
elif "Maşınlar və avadanlıqlar" in asset_type:
|
||||||
|
return "machinery_equipment"
|
||||||
|
elif "Yüksək texnologiyalar" in asset_type and "hesablama texnikası" in asset_type:
|
||||||
|
return "high_tech_computing"
|
||||||
|
elif "Nəqliyyat vasitələri" in asset_type:
|
||||||
|
return "transport_vehicles"
|
||||||
|
elif "Digər əsas vəsaitlər" in asset_type:
|
||||||
|
return "other_fixed_assets"
|
||||||
|
else:
|
||||||
|
return "other_asset_type"
|
||||||
|
|
||||||
|
|
||||||
|
def get_taxable_assets(filters, taxable_asset_types):
|
||||||
|
"""Получает активы с типом 'Vergiyə cəlb olunan əsas vəsaitlər' исключая активы года создания компании"""
|
||||||
|
|
||||||
|
conditions = []
|
||||||
|
values = []
|
||||||
|
|
||||||
|
# Фильтр по компании
|
||||||
|
if filters.get("company"):
|
||||||
|
conditions.append("a.company = %s")
|
||||||
|
values.append(filters.get("company"))
|
||||||
|
|
||||||
|
# Фильтр по датам
|
||||||
|
if filters.get("from_date"):
|
||||||
|
conditions.append("a.purchase_date <= %s")
|
||||||
|
values.append(filters.get("to_date"))
|
||||||
|
|
||||||
|
# Фильтр по asset type
|
||||||
|
conditions.append("a.custom_asset_type = %s")
|
||||||
|
values.append("Vergiyə cəlb olunan əsas vəsaitlər")
|
||||||
|
|
||||||
|
# Фильтр по taxable asset types
|
||||||
|
asset_type_placeholders = ", ".join(["%s"] * len(taxable_asset_types))
|
||||||
|
conditions.append(f"a.taxable_asset_type IN ({asset_type_placeholders})")
|
||||||
|
values.extend(taxable_asset_types)
|
||||||
|
|
||||||
|
# Только подтвержденные активы
|
||||||
|
conditions.append("a.docstatus = 1")
|
||||||
|
|
||||||
|
# ИСКЛЮЧАЕМ активы года создания компании
|
||||||
|
conditions.append("YEAR(a.purchase_date) != YEAR(c.date_of_establishment)")
|
||||||
|
|
||||||
|
where_clause = ""
|
||||||
|
if conditions:
|
||||||
|
where_clause = "WHERE " + " AND ".join(conditions)
|
||||||
|
|
||||||
|
# Исключаем капитализированные активы (как в стандартном отчете)
|
||||||
|
exclude_capitalized = """
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
where_clause += exclude_capitalized
|
||||||
|
values.append(filters.get("from_date"))
|
||||||
|
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name,
|
||||||
|
a.purchase_date,
|
||||||
|
a.taxable_asset_type,
|
||||||
|
a.insured_value
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
JOIN
|
||||||
|
`tabCompany` c ON a.company = c.name
|
||||||
|
{where_clause}
|
||||||
|
ORDER BY
|
||||||
|
a.purchase_date DESC, a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset_balances(filters, asset_names):
|
||||||
|
"""Рассчитывает остатки активов на основе стандартной логики"""
|
||||||
|
|
||||||
|
if not asset_names:
|
||||||
|
return []
|
||||||
|
|
||||||
|
asset_placeholders = ", ".join(["%s"] * len(asset_names))
|
||||||
|
|
||||||
|
# Используем ту же логику что в стандартном отчете для расчета остатков
|
||||||
|
query = f"""
|
||||||
|
SELECT
|
||||||
|
a.name as asset,
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date < %s THEN
|
||||||
|
CASE WHEN IFNULL(a.disposal_date, 0) = 0 OR a.disposal_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_as_on_from_date,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN a.purchase_date >= %s THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_new_purchase,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Sold" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_sold_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Scrapped" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_scrapped_asset,
|
||||||
|
|
||||||
|
IFNULL(SUM(CASE WHEN IFNULL(a.disposal_date, 0) != 0
|
||||||
|
AND a.disposal_date >= %s
|
||||||
|
AND a.disposal_date <= %s THEN
|
||||||
|
CASE WHEN a.status = "Capitalized" THEN
|
||||||
|
a.gross_purchase_amount
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END
|
||||||
|
ELSE
|
||||||
|
0
|
||||||
|
END), 0) as value_of_capitalized_asset
|
||||||
|
FROM
|
||||||
|
`tabAsset` a
|
||||||
|
WHERE
|
||||||
|
a.docstatus = 1
|
||||||
|
AND a.company = %s
|
||||||
|
AND a.purchase_date <= %s
|
||||||
|
AND a.name IN ({asset_placeholders})
|
||||||
|
AND NOT EXISTS(
|
||||||
|
SELECT 1 FROM `tabAsset Capitalization Asset Item` acai
|
||||||
|
JOIN `tabAsset Capitalization` ac ON acai.parent = ac.name
|
||||||
|
WHERE acai.asset = a.name
|
||||||
|
AND ac.posting_date < %s
|
||||||
|
AND ac.docstatus = 1
|
||||||
|
)
|
||||||
|
GROUP BY a.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = [
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 1
|
||||||
|
filters.get("from_date"), # value_as_on_from_date condition 2
|
||||||
|
filters.get("from_date"), # value_of_new_purchase
|
||||||
|
filters.get("from_date"), # value_of_sold_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_sold_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_scrapped_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_scrapped_asset condition 2
|
||||||
|
filters.get("from_date"), # value_of_capitalized_asset condition 1
|
||||||
|
filters.get("to_date"), # value_of_capitalized_asset condition 2
|
||||||
|
filters.get("company"), # company filter
|
||||||
|
filters.get("to_date"), # purchase_date filter
|
||||||
|
*asset_names, # asset names for IN clause
|
||||||
|
filters.get("from_date") # capitalization exclusion
|
||||||
|
]
|
||||||
|
|
||||||
|
return frappe.db.sql(query, values, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_columns(filters):
|
||||||
|
"""Создает колонки отчета"""
|
||||||
|
columns = []
|
||||||
|
|
||||||
|
# Основные колонки
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": "Əmlak",
|
||||||
|
"fieldname": "asset",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "Asset",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Tarix",
|
||||||
|
"fieldname": "purchase_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"width": 100
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
# Создаем колонки для каждого типа taxable asset
|
||||||
|
taxable_asset_types = get_taxable_asset_types_list()
|
||||||
|
|
||||||
|
for asset_type in taxable_asset_types:
|
||||||
|
asset_type_key = get_field_key(asset_type)
|
||||||
|
|
||||||
|
# Сокращенное название для заголовка колонки
|
||||||
|
short_name = get_short_asset_type_name(asset_type)
|
||||||
|
|
||||||
|
columns.extend([
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.day_before_from_date) + " əsasən",
|
||||||
|
"fieldname": f"{asset_type_key}_value_from",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Qiymət " + formatdate(filters.to_date) + " əsasən",
|
||||||
|
"fieldname": f"{asset_type_key}_value_to",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": f"{short_name} - " + "Sığorta dəyəri",
|
||||||
|
"fieldname": f"{asset_type_key}_insured",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"width": 120
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
return columns
|
||||||
|
|
||||||
|
|
||||||
|
def get_short_asset_type_name(asset_type):
|
||||||
|
"""Создает короткое название для заголовка колонки"""
|
||||||
|
if "Binalar, tikililər və qurğular" in asset_type:
|
||||||
|
return "Binalar və Qurğular"
|
||||||
|
elif "Çoxmərtəbəli" in asset_type and "yaşayış binalar" in asset_type:
|
||||||
|
return "Çoxmərtəbəli Binaları"
|
||||||
|
elif "Qeyri-yaşayış binaları" in asset_type:
|
||||||
|
return "Qeyri-yaşayış Binaları"
|
||||||
|
elif "Əmlak kompleksi kimi müəssisələr" in asset_type:
|
||||||
|
return "Əmlak Kompleksləri"
|
||||||
|
elif "Qurğular" == asset_type:
|
||||||
|
return "Qurğular"
|
||||||
|
elif "Mənzillər" in asset_type:
|
||||||
|
return "Mənzillər"
|
||||||
|
elif "Fərdi yaşayış və bağ evləri" in asset_type:
|
||||||
|
return "Fərdi Yaşayış Evləri"
|
||||||
|
elif "Maşınlar və avadanlıqlar" in asset_type:
|
||||||
|
return "Maşın və Avadanlıqlar"
|
||||||
|
elif "Yüksək texnologiyalar" in asset_type and "hesablama texnikası" in asset_type:
|
||||||
|
return "Yüksək Texnologiyalar"
|
||||||
|
elif "Nəqliyyat vasitələri" in asset_type:
|
||||||
|
return "Nəqliyyat Vasitələri"
|
||||||
|
elif "Digər əsas vəsaitlər" in asset_type:
|
||||||
|
return "Digər Əsas Vəsaitlər"
|
||||||
|
else:
|
||||||
|
return "Digər"
|
||||||
Loading…
Reference in New Issue