Passed
Push — main ( ec6df3...a90a67 )
by Sat CFDI
02:39
created

satdigitalinvoice.layout.make_layout()   F

Complexity

Conditions 13

Size

Total Lines 441
Code Lines 344

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 344
dl 0
loc 441
rs 2.94
c 0
b 0
f 0
cc 13
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like satdigitalinvoice.layout.make_layout() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from datetime import date, datetime, timedelta
2
from enum import StrEnum
3
4
import PySimpleGUI as sg
5
from satcfdi.models import Code
6
from satcfdi.catalogs import select_all
7
from satcfdi.pacs.sat import TipoDescargaMasivaTerceros
8
9
from satdigitalinvoice.gui_functions import mf_pago_fmt, CALENDAR_FECHA_FMT
10
11
FORMA_PAGO = select_all('C756_c_FormaPago')
12
TEXT_PADDING = ((5, 0), 3)
13
14
# 24 x 24
15
FOLDER_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAqElEQVR4nO3UsQnCYBRF4U/EAcRJtHUJcQddwQlsxcpVLF0hOoY2FlaC+SUQQWI0PmwscuF0j3PhFZc2" \
16
              "/5QR9siRnjhhid6vBVlFXGWHwS8Ft4aCHLPydozFGybo1BV8kl8wLe/muDbcryIFBwzRxbpB/OAcfV8f2y/lD17y7qcbHIPy2oKoILUFqX1RdCpSgMIVHrsUoHDVznVWM9cpQF46imlp8ye5AyE7C1To4" \
17
              "/HLAAAAAElFTkSuQmCC"
18
19
EXCEL_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA7klEQVR4nN2VQQqCUBCGv2pfFyhv0FmC7hGFq1bhrgi6gi1cBK6CdhFtvYdCi6CgrZsXwgTyUNOnLmrgBx31" \
20
             "/+DNOAP/HkNgCqyBK3AHLsDA1HAELIEjcANUjuYm5hbwKDBVKTnyjZ5/ATugkwWwS5qrAsBHkyyA0yBg1SQgAraiSHueCwgBL3V" \
21
             "/kFwWwAd6Ir8swJXcSZTEvsIRfQXEwFg6y5LruElAogDoioKma1AF4JvUoPUjctsucqi1qVfQpsY1KPuj+SY1qDsqnLaH3SJvF9Qd1wp4ilethTOT9zea7CLzsivzDPSrmPx2vAFRfA9plcmcVwAAAABJRU5ErkJggg=="
22
23
HTML_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA/ElEQVR4nN2VOwoCMRCGPz2HB7ARHyfwBN5EsLOxWKzs7Ox0e69gYbOtoK2dZ7BVRwZGWJbsJvuw0IGfDUkmX" \
24
            "/gzm8A/xgi4AC9AHNLo1gGccxaWFCAC1lUBz0CAVIVICYAYpPVNgJSF+ABtYOHoXzcF6AMdYAmsMuo1ATgZpJTvZQAScEa5ETcAiIsA+vcmDm9XgUpsjUJ7tASnGV1tTL8z26VeKTdgAOwz5esFqA6mKDX2WUR3ebe" \
25
            "+MXCsAkhMLsAGmNQBZC3C7MHRpxY9rO0FvMyWeUUdfIe8a6BMt9S8rqVAmlv7wZECaa43RjYx78kUh3Su5gxDAL8Vb7wE7yjidnvCAAAAAElFTkSuQmCC"
26
27
PDF_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA+0lEQVR4nN3VPUrEQBQA4E89gCBio7WI" \
28
           "+INbeAbxAoI3ESzEysoFd21tbe28QixE7a2t7dxGRwKvWCTrTpJNoQ9ek5k3X8hM5vEfo4cXfCFVZBkbbYDnCQunMeAM" \
29
           "/abAZyaQmiKpBpACmesSSHWRacA8Tiue92cF7GIN57j4kduzAB4DqfXdc4ACQ3xk7FEjYBk7GHQFrOMQl10BJ3GC7roC3mL8vivgNsYXsYmlyKIt8IojLOAYV1jFQWz6sA1QxOnZwv" \
30
           "7YFf6OG1xj1AYYRH9YwVPGT5jqXtejeMuHzMXL2tYNJ/2SZe3U6MXESS0zVWQ5t6zZywH+VnwDCQv1frFQIlYAAAAASUVORK5CYII="
31
32
ABOUT_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABP0lEQVR4nOWVTU7DMBCFvxuwKmrX0G4o5QLtQboDFXEbwrLkGNDucwB" \
33
             "+VvQObS5ApCxAIz1LCNmOG68QTxopst882y/jMfwHnAIroAQ2ilJjgxzhkYRa4AvYA6" \
34
             "+KvcZacYx7FBZADXwC98DUw7GxAmjEXRwjbkkfwHkCfyyu5cy7yCPtxhJOUnckruUcgGGMWMqWs8D8UhE6iZ3iMVYtrTwPoVKEUEjDW123qowL" \
35
             "+uNSGjche6z8YlhGLHI4hGzaAi8dyVWHReiePPsmNprMXeAdeOprUZWwQB2yaKUfNM1Y4Eoa17EyLTIWeIiVqbOp0aXx4U7hw0S565RWsevRKnYpreJ3sxsniE8kntTsHObaTaN" \
36
             "/MvNwZvK8ETdZ3GGocnMPjom8KeofD846xZYYBuotJmQ31MK+bSzryfwb+AbymF7gpXVM1QAAAABJRU5ErkJggg=="
37
38
REFRESH_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABGUlEQVR4nO3VzSqFURTG8Z8JYmRiJN9yDQYiKbdhYqDO9OQWyMSQDGRISoYMlHIJJEWZ" \
39
               "+v4oysTRrqU4nePdZej91+ptt3frWWu31/NS8kdaMINNXOANLzjFGia/ne3CdHyzGMUxarjBNpawgt0QSnsHGA6xWp1oU8bxhGvMorXBmQ5UQugO1VyBITziBD0ZxQziCh+5Aoe4z0y+ELEeyQsF0r2" \
40
               "/Y14etQZR2EE32jIFSv4Z7fFAfuVr3Osjh0o88ZFcgS0sRhTRF9OffEmOQBr7S/RnJO/FWUz" \
41
               "/QK5ANQzsOVrvbHA2DeMcbvGAsYxiflhuMr39WCfH3AurXsZOFJD2joruXcFPYwKr4a6po1ecYwNTuYlLNOMTqXpPNQBv/ywAAAAASUVORK5CYII="
42
43
PREVIEW_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABKElEQVR4nO2VMU8CQRCFP6WAQksqOxJ/A6WJUFFprJSEilARWgsa" \
44
               "/4IVLYUNFZ0WVECwNxpCIDQYfwEVGj0zycNcCOTulqMxvGQze2/eztub3O3Cf0QJ6IQYD8CRi8Ed4AUUn0rTczFZGoTRfLmYRDG4Aj6BAXC8C4M80NC8H/ZNohh4K6Mel0FGu" \
45
               "/cPT2tjMViHvUEg9i0KxBmQjeszPVSxCnCrmBW/lUECqAKzDX/yTPmEi0EaeFauq0JDzU+BG809HX7pKAYnwAiYA9fi7qVr+jZgKEo30rqNBh2dlAe65Yx7BJLStX2teQFa4i3/JN7WBV6Z5+JrwA/wKu4S" \
46
               "+FYhixdADniTzvSRUQDeVXSsNiwUJ+ItbzpnpICy2vAhA4v2bLzl//ALOtSCJzC7jH4AAAAASUVORK5CYII="
47
48
SEARCH_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABM0lEQVR4nOXTuytAYRzG8Y8RJTPJ5jJIitwGoxiZGSTZDAaDTQaJhYWBf0A" \
49
              "WRDHjD7BIMrkUg2wol079lEGc1yXJU2c4b8/5Pu/vfZ/Df1MjJrGKLSyjHyVfBZdjE0+4wwH2cB5rVxj8LLwmQNcYeWO3TdiOoJlUeDGOcIbqd3wFmI2QgZSAcTyiPYc3C9nBZcq" \
50
              "dnGAjYUPNMUVfHnNlmIcSArIpLrCUx9wSAZ3StB8V/lD1EdCTGJBVeCVvg+4wlQAvxT0m8n6wERUtyukfjakb8ga04QELOby1uMGaxFbsxq4W49jeUke05xRlKfD5gO/GJBlkGr3" \
51
              "ownA0JvsZD1H1Gfh8vLdiHbex/vIcYwyFX4G/VnbhdRFYIVEZbO7VmRekAn4Nnqn7nWP5NnX9JNyf1DM+Yku7BVpvYgAAAABJRU5ErkJggg=="
52
53
CONFIG_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABPElEQVR4nOWVvWoCQRSFP5NCSJHOdGkECaa3s" \
54
              "/MtUu6CYOcTaGMZU2efwNYtrKwkWPgK9nmAEC38IRMGTmCZrIMru6B44MLOmXPP7N6ZvQPXgiowdcJyueEFMMBMYcTlhjfgG7hR2OfhqWYB0AEqQBnoA1/APKGZi" \
55
              "+tLU1GOzfXiEVirBDvgE9gA70A9oauL20izU85aHgcxAlZACxgAH0DDo29IM1DOSh6paAI/QJQyVwJCIFaE4lxE8rBe//AALIA90HbMY5VgqTDikou0lbuQVyrugIkMnsSFGttN/ENHnJ1DWqNc6+FFV" \
56
              "+J7jWO9tYul5pDWKJc8FxhnXSBriQKNa8eUqPBNbh5xTMeK4JRjWviP5msVkdMqnsVts7aKtGbX8zS7XtZmdwhDff5tol2/ckkXTrXoK/N88Qvnr38CSEQRlwAAAABJRU5ErkJggg=="
57
58
EDIT_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA10lEQVR4nO3UPUpDQRSG4cfCQgn" \
59
            "+LSPLSCcEC1u3EXdgEXdg3EC2IXYS0N4itZWWGkGvDHyBkE45Npq3usyB95tz5s6w4ZfZwwQveMIFtqvkB5jhDZe4xmdCyuQdxivrk3RSIl/gAe84Ta118oytCvkQPdwmZJxxXVXJl/TSSZd6O/hvs4+7yE" \
60
            "/Wasd4xT2ONvIl/3gsuys3dLRWGyZ0ll/2RwwiX2SnZ5XyxnkerD5uEjKqkjemmOe7H3FXJW885rGaR9xVyg/xkZBpxjXIwZewU7VTf4ovf6VSMafchm4AAAAASUVORK5CYII="
61
62
ZIP_ICON = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAt0lEQVR4nOXVPQrCQBCG4Qd7wTPYWtulsPAa5hq2KS0svYRnSKuNvZ3aWXgDESQibBECgWQl4s8HA8vAzMs3u" \
63
           "+zwi0qRR0baBJChiGhehNrGgLYq/gcwxSICsAi1n6NJsF1U7FfPz9hj1BYwDLa3ocmsBrDBBesYF32csUOvBnDCFasYwBJ3jEu5KuAYmg9iRnTDAXMkNYBGT/OVS858mpIwkraal8b4439R9i5A3tXC6Xxl" \
64
           "+io9AMiJawPDOx2QAAAAAElFTkSuQmCC"
65
66
IMPORT_CSV = "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsTAAALEwEAmpwYAAABVElEQVR4nN3Vv0scYRDG8U+EQApjl4AIAYMIFqIEhGAnpLBJIRZ2goV" \
67
             "/gZIiIqY8rkklIb2VlWjAYq1yXGVvlzSSIlqKkZjIhoM5OJaL9+6qCTgwsDs7z3zfeff9wX20RWQJvoX+KoB3yHsU/xI5n6tA2oCUnF9VIGUA87hEE4/vAvAKH+K5kdpJGUBe8LXbAjyP0Xd6HtrkZVrWstD+f+vDW" \
68
             "+xiLmLj2MZHPCl0WbrjhZjPb7EEh3CEU/zAOpYiZxKf8LUMYCPEI6jFDz3DYfhYdPEb7/ET9TKAbqtoGt9xheWINWInt3KnygDehKjWIR7GaxzjIPJW43treh5EbBY7eHQdoFXsJMRNPMRmvJ" \
69
             "/jZeSNRqzeUfwiYvu9IAN4EcXFCCcwWMibwdNC8bwXpL1LU+0Z9grHePtYX6l6VPzNkrQpF07WxZMBqVdmVhVwE/v3gD+of4e/h7E8SwAAAABJRU5ErkJggg=="
70
71
BUTTON_COLOR = (sg.theme_background_color(), sg.theme_background_color())
72
LARGE_FONT = ("Courier New", 11, "bold")
73
PERIODO_FMT = "%Y-%m"
74
75
76
class TipoRecuperar(StrEnum):
77
    Emitidas = 'Emitidas'
78
    Recibidas = 'Recibidas'
79
80
81
class SearchOptions(StrEnum):
82
    PorPagar = 'Por Pagar'
83
    PorEnviar = 'Por Enviar'
84
    Hoy = datetime.now().strftime(CALENDAR_FECHA_FMT)
85
    Mes = datetime.now().strftime(PERIODO_FMT)
86
    Anio = datetime.now().strftime("%Y")
87
88
89
class MyTable(sg.Table):
90
    def __init__(self, key, headings, row_fn):
91
        super().__init__(
92
            values=[],
93
            key=key,
94
            headings=headings,
95
            expand_x=True,
96
            expand_y=True,
97
            select_mode=sg.TABLE_SELECT_MODE_EXTENDED,
98
            enable_events=True,
99
            text_color="black",
100
            background_color="white",
101
            # headings=HEADINGS,
102
            # values=[],
103
            # auto_size_columns=False,
104
            # col_widths=COL_WIDTHS,
105
            # justification="center",
106
            # num_rows=20,
107
            alternating_row_color="grey95",  # "aliceblue",
108
            # row_height=ROW_HEIGHT,
109
            # header_text_color="white",
110
            # header_background_color="darkblue",
111
            # font=FONT,
112
            # bind_return_key=True,
113
            # tooltip="Doble click para ver factura",
114
            # right_click_menu=RIGHT_CLICK_MENU
115
            metadata=True
116
        )
117
        self.row_fn = row_fn
118
119
    def selected_items(self):
120
        return [self.metadata[i] for i in self.SelectedRows]
121
122
    def select_all(self):
123
        self.update(
124
            select_rows=list(range(len(self.metadata)))
125
        )
126
127
    def delete_selected(self):
128
129
        def iter_metadata():
130
            s = 0
131
            for i in self.SelectedRows + [len(self.metadata)]:
132
                for j in range(s, i):
133
                    yield self.metadata[j]
134
                s = i + 1
135
136
        self.update(
137
            values=list(iter_metadata())
138
        )
139
140
    def update(self, values=None, **kwargs):
141
        if values is not None:
142
            super().update(
143
                values=[
144
                    self.row_fn(i, item)
145
                    for i, item in enumerate(values, start=1)
146
                ],
147
                **kwargs
148
            )
149
            self.metadata = values
150
        else:
151
            super().update(**kwargs)
152
153
    def refresh(self):
154
        self.update(
155
            self.metadata,
156
            select_rows=self.SelectedRows
157
        )
158
159
160
def make_layout(has_fiel, local_db):
161
    # ----- Full layout -----
162
    return [
163
        [
164
            sg.TabGroup(
165
                [[
166
                    sg.Tab(
167
                        'Emitidas '.center(13),
168
                        [
169
                            [
170
                                sg.Column([[
171
                                    sg.Button(image_data=IMPORT_CSV, key="importar_emitidas", border_width=0, button_color=BUTTON_COLOR),
172
                                    sg.ButtonMenu(
173
                                        image_data=SEARCH_ICON, button_text="", key="buscar_facturas", border_width=0, button_color=BUTTON_COLOR,
174
                                        menu_def=[
175
                                            [],
176
                                            [str(o) for o in SearchOptions],
177
                                        ],
178
                                    ),
179
                                    sg.Input(datetime.now().strftime(PERIODO_FMT), size=(40, 1), key="emitidas_search"),
180
                                ]],
181
                                    expand_x=True
182
                                )
183
                            ],
184
                            [
185
                                sg.HorizontalSeparator(color="black"),
186
                            ],
187
                            [
188
                                sg.Column([[
189
                                    sg.Button("".ljust(10), key="status_sat", border_width=0, button_color=sg.theme_background_color()),
190
                                    sg.Button("".ljust(10), key="email_notificada", border_width=0, button_color=sg.theme_background_color()),
191
                                    sg.Button("".ljust(10), key="pendiente_pago", border_width=0, button_color=sg.theme_background_color()),
192
                                ]]),
193
                                sg.VSeparator(color="black"),
194
                                sg.Column([[
195
                                    sg.CalendarButton("FechaPago:", format=CALENDAR_FECHA_FMT, title="FechaPago", no_titlebar=False, target="fecha_pago", pad=TEXT_PADDING,
196
                                                      border_width=0),
197
                                    sg.Input(datetime.now().strftime(CALENDAR_FECHA_FMT), size=(12, 1), key="fecha_pago"),
198
                                    sg.Text("FormaPago:", pad=TEXT_PADDING, border_width=0),
199
                                    sg.Combo([Code(k, v) for k, v in FORMA_PAGO.items()],
200
                                             default_value=Code("03", FORMA_PAGO["03"]), key="forma_pago", size=(35, 1)),
201
                                    sg.Text("ImpPagado:", pad=TEXT_PADDING, border_width=0),
202
                                    sg.Input("", size=(12, 1), key="importe_pago"),
203
                                ]], visible=False, key="ppd_action_items"),
204
                            ],
205
                            [
206
                                MyTable(
207
                                    key="emitidas_table",
208
                                    headings=[
209
                                        '#',
210
                                        'Receptor Razon Social',
211
                                        'Recep. Rfc',
212
                                        'Factura',
213
                                        "Fecha",
214
                                        "Total",
215
                                        "Pendiente",
216
                                        "Status",
217
                                        "Tipo",
218
                                        "Folio"
219
                                    ],
220
                                    row_fn=lambda i, r: [
221
                                        i,
222
                                        r['Receptor'].get('Nombre', ''),
223
                                        r['Receptor']['Rfc'],
224
                                        r.name,
225
                                        r["Fecha"].strftime(CALENDAR_FECHA_FMT),
226
                                        r["Total"],
227
                                        r.saldo_pendiente if r.saldo_pendiente else "",
228
                                        str(local_db.liquidated_state(r)) + str(" 📧" if local_db.notified(r) else "   "),
229
                                        mf_pago_fmt(r),
230
                                        r.uuid
231
                                    ]
232
                                )
233
                            ]],
234
                        key='emitidas_tab',
235
                    ),
236
                    sg.Tab(
237
                        'Recibidas '.center(13),
238
                        [
239
                            [
240
                                sg.Column([[
241
                                    sg.Button(image_data=IMPORT_CSV, key="importar_recibidas", border_width=0, button_color=BUTTON_COLOR),
242
                                    sg.ButtonMenu(
243
                                        image_data=SEARCH_ICON, button_text="", key="buscar_facturas_recibidas", border_width=0, button_color=BUTTON_COLOR,
244
                                        menu_def=[
245
                                            [],
246
                                            [str(o) for o in SearchOptions],
247
                                        ],
248
                                    ),
249
                                    sg.Input(datetime.now().strftime(PERIODO_FMT), size=(40, 1), key="recibidas_search"),
250
                                ]],
251
                                    expand_x=True
252
                                )
253
                            ],
254
                            [
255
                                sg.HorizontalSeparator(color="black"),
256
                            ],
257
                            [
258
                                MyTable(
259
                                    key="recibidas_table",
260
                                    headings=[
261
                                        '#',
262
                                        'Emisor Razon Social',
263
                                        'Emisor Rfc',
264
                                        'Factura',
265
                                        "Fecha",
266
                                        "Total",
267
                                        "Pendiente",
268
                                        "Status",
269
                                        "Tipo",
270
                                        "Folio"
271
                                    ],
272
                                    row_fn=lambda i, r: [
273
                                        i,
274
                                        r['Emisor'].get('Nombre', ''),
275
                                        r['Emisor']['Rfc'],
276
                                        r.name,
277
                                        r["Fecha"].strftime(CALENDAR_FECHA_FMT),
278
                                        r["Total"],
279
                                        r.saldo_pendiente if r.saldo_pendiente else "",
280
                                        str(local_db.liquidated_state(r)) + str(" 📧" if local_db.notified(r) else "   "),
281
                                        mf_pago_fmt(r),
282
                                        r.uuid
283
                                    ]
284
                                )
285
                            ]],
286
                        key='recibidas_tab',
287
                    ),
288
                    sg.Tab(
289
                        'Facturas '.center(13),
290
                        [
291
                            [
292
                                sg.Button(image_data=EDIT_ICON, key="editar_facturas", border_width=0, button_color=BUTTON_COLOR),
293
                                sg.Text("Periodo:", pad=TEXT_PADDING),
294
                                sg.Input(date.today().strftime(PERIODO_FMT), size=(11, 1), key="facturas_periodo"),
295
                                sg.Text("", pad=TEXT_PADDING, key="preparar_facturas_text", font=LARGE_FONT),
296
                            ],
297
                            [
298
                                MyTable(
299
                                    key="facturas_table",
300
                                    headings=[
301
                                        '#',
302
                                        'EReg',
303
                                        'Receptor Razon Social',
304
                                        'Recep. Rfc',
305
                                        "Tipo",
306
                                        "Subtotal",
307
                                        "Total"
308
                                    ],
309
                                    row_fn=lambda i, r: [
310
                                        i,
311
                                        r['Emisor']['RegimenFiscal'].code,
312
                                        r['Receptor']['Nombre'],
313
                                        r['Receptor']['Rfc'],
314
                                        mf_pago_fmt(r),
315
                                        r['SubTotal'],
316
                                        r['Total']
317
                                    ]
318
                                )
319
                            ]],
320
                        key='facturas_tab',
321
                    ),
322
                    sg.Tab(
323
                        'Correos'.center(13),
324
                        [
325
                            [
326
                                sg.Text("", pad=TEXT_PADDING),
327
                            ],
328
                            [
329
                                MyTable(
330
                                    key="correos_table",
331
                                    headings=[
332
                                        '#',
333
                                        'Receptor Razon Social',
334
                                        'Recep. Rfc',
335
                                        'Facturas',
336
                                        'Pendientes Emitidas Meses Anteriores'
337
                                    ],
338
                                    row_fn=lambda i, r: [
339
                                        i,
340
                                        r[0]["RazonSocial"],
341
                                        r[0]["Rfc"],
342
                                        ",".join(n.name for n in r[1]),
343
                                        ",".join(n.name for n in r[2])
344
                                    ]
345
                                )
346
                            ]],
347
                        key='correos_tab',
348
                    ),
349
                    sg.Tab(
350
                        'Ajustes'.center(13),
351
                        [
352
                            [
353
                                sg.Button(image_data=EDIT_ICON, key="editar_ajustes", border_width=0, button_color=BUTTON_COLOR),
354
                                sg.Text("Periodo:", pad=TEXT_PADDING),
355
                                sg.Input(date.today().strftime(PERIODO_FMT), size=(11, 1), key="ajustes_periodo"),
356
                                sg.Text("", pad=TEXT_PADDING, key="preparar_ajustes_text", font=LARGE_FONT),
357
                            ],
358
                            [
359
                                MyTable(
360
                                    key="ajustes_table",
361
                                    headings=[
362
                                        "#",
363
                                        "Receptor Razon Social",
364
                                        "Recep. Rfc",
365
                                        "Actual",
366
                                        "Nuevo",
367
                                        "Ajuste %",
368
                                        "Periodo",
369
                                        "Meses",
370
                                        "Ajuste Efectivo"
371
                                    ],
372
                                    row_fn=lambda i, r: [
373
                                        i,
374
                                        r["receptor"]["RazonSocial"],
375
                                        r["receptor"]["Rfc"],
376
                                        r["valor_unitario"],
377
                                        r["valor_unitario_nuevo"],
378
                                        r["ajuste_porcentaje"],
379
                                        r["periodo"],
380
                                        r["meses"],
381
                                        r["efectivo_periodo_desc"]
382
                                    ]
383
                                )
384
                            ]],
385
                        key='ajustes_tab'
386
                    ),
387
                    sg.Tab(
388
                        'Depositos'.center(13),
389
                        [
390
                            [
391
                                sg.Button(image_data=EDIT_ICON, key="editar_depositos", border_width=0, button_color=BUTTON_COLOR),
392
                                sg.Text("Periodo:", pad=TEXT_PADDING),
393
                                sg.Input(date.today().strftime(PERIODO_FMT), size=(11, 1), key="depositos_periodo"),
394
                                sg.Text("", pad=TEXT_PADDING, key="preparar_depositos_text", font=LARGE_FONT),
395
                            ],
396
                            [
397
                                MyTable(
398
                                    key="depositos_table",
399
                                    headings=[
400
                                        "#",
401
                                        "Receptor Razon Social",
402
                                        "Recep. Rfc",
403
                                        "Actual",
404
                                    ],
405
                                    row_fn=lambda i, r: [
406
                                        i,
407
                                        r["receptor"]["RazonSocial"],
408
                                        r["receptor"]["Rfc"],
409
                                        r["valor_unitario"],
410
                                    ]
411
                                )
412
                            ]],
413
                        key='depositos_tab'
414
                    ),
415
                    sg.Tab(
416
                        'Clientes '.center(13),
417
                        [
418
                            [
419
                                sg.Button(image_data=EDIT_ICON, key="editar_clientes", border_width=0, button_color=BUTTON_COLOR),
420
                                sg.Push(),
421
                                sg.Button("Exportar", key="exportar_clientes", border_width=0),
422
                            ],
423
                            [
424
                                MyTable(
425
                                    key="clientes_table",
426
                                    headings=[
427
                                        "#",
428
                                        "Razon Social",
429
                                        "Rfc",
430
                                        "Reg",
431
                                        "CP",
432
                                        "IdCIF"
433
                                    ],
434
                                    row_fn=lambda i, r: [
435
                                        i,
436
                                        r["RazonSocial"],
437
                                        r["Rfc"],
438
                                        r["RegimenFiscal"],
439
                                        r["CodigoPostal"],
440
                                        r["IdCIF"]
441
                                    ]
442
                                )
443
                            ]],
444
                        key='clientes_tab',
445
                    ),
446
                    sg.Tab(
447
                        'Solicitudes'.center(13),
448
                        [
449
                            [
450
                                sg.Column([[
451
                                    sg.Button(image_data=ZIP_ICON, key="cargar_zip", border_width=0, button_color=BUTTON_COLOR),
452
                                    sg.Text("Recuperar:", pad=TEXT_PADDING),
453
                                    sg.Combo([TipoRecuperar.Recibidas, TipoRecuperar.Emitidas], default_value=TipoRecuperar.Recibidas, key="tipo_recuperar", size=(10, 1)),
454
455
                                    sg.CalendarButton("Inicio:", format=CALENDAR_FECHA_FMT, title="Inicio", no_titlebar=False, target="fecha_inicial", pad=TEXT_PADDING,
456
                                                      border_width=0),
457
                                    sg.Input((datetime.now() - timedelta(days=40)).strftime(CALENDAR_FECHA_FMT), size=(12, 1), key="fecha_inicial"),
458
459
                                    sg.CalendarButton("Final:", format=CALENDAR_FECHA_FMT, title="Final", no_titlebar=False, target="fecha_final", pad=TEXT_PADDING,
460
                                                      border_width=0),
461
                                    sg.Input(datetime.now().strftime(CALENDAR_FECHA_FMT), size=(12, 1), key="fecha_final"),
462
463
                                    sg.Text("Tipo:", pad=TEXT_PADDING),
464
                                    sg.Combo([TipoDescargaMasivaTerceros.CFDI, TipoDescargaMasivaTerceros.METADATA], default_value=TipoDescargaMasivaTerceros.CFDI,
465
                                             key="tipo_solicitud", size=(10, 1)),
466
467
                                    sg.Button("Nueva Solicitud", key="nueva_solicitud", border_width=0),
468
                                ]],
469
                                    expand_x=True
470
                                )
471
                            ],
472
                            [
473
                                MyTable(
474
                                    key="solicitudes_table",
475
                                    headings=[
476
                                        "#",
477
                                        "IdSolicitud",
478
                                        "Mensaje",
479
                                        "EstadoSolicitud",
480
                                        "FechaInicial",
481
                                        "FechaFinal",
482
                                        "TipoSolicitud",
483
                                        "RfcReceptor",
484
                                        "RfcEmisor",
485
                                    ],
486
                                    row_fn=lambda i, r: [
487
                                        i,
488
                                        r["response"]["IdSolicitud"],
489
                                        r["response"]["Mensaje"],
490
                                        r["response"].get("EstadoSolicitud", ""),
491
                                        r["request"]["fecha_inicial"].strftime(CALENDAR_FECHA_FMT),
492
                                        r["request"]["fecha_final"].strftime(CALENDAR_FECHA_FMT),
493
                                        r["request"]["tipo_solicitud"],
494
                                        r["request"]["rfc_receptor"] or "",
495
                                        r["request"]["rfc_emisor"] or "",
496
                                    ]
497
                                )
498
                            ]
499
                        ],
500
                        key='solicitudes_tab',
501
                        # visible=has_fiel
502
                    ),
503
                    sg.Tab(
504
                        'Contabilidad '.center(13),
505
                        [[
506
                            sg.Column([[
507
                                sg.Text("Periodo:", pad=TEXT_PADDING),
508
                                sg.Input(date.today().strftime(PERIODO_FMT), size=(11, 1), key="periodo"),
509
                                sg.Button(image_data=EXCEL_ICON, key="ver_excel", border_width=0, button_color=BUTTON_COLOR),
510
                                sg.Button(image_data=FOLDER_ICON, key="ver_carpeta", border_width=0, button_color=BUTTON_COLOR),
511
                            ]])
512
                        ]],
513
                        key='contabilidad_tab',
514
                    ),
515
                    sg.Tab(
516
                        'Consola'.center(13),
517
                        [
518
                            [
519
                                sg.Push(),
520
                                sg.Button(image_data=ABOUT_ICON, key="about", border_width=0, button_color=BUTTON_COLOR),
521
                            ],
522
                            [sg.Multiline(
523
                                expand_x=True,
524
                                expand_y=True,
525
                                key="console",
526
                                write_only=True,
527
                                autoscroll=True,
528
                                reroute_stdout=True
529
                            )]
530
                        ],
531
                        key='errores_tab',
532
                    ),
533
                    sg.Tab(
534
                        'Configuracion'.center(13),
535
                        [
536
                            [
537
                                sg.Column([[
538
                                    sg.Button(image_data=EDIT_ICON, key="editar_configurar", border_width=0, button_color=BUTTON_COLOR),
539
                                    sg.Button(image_data=CONFIG_ICON, key="ver_config", border_width=0, button_color=BUTTON_COLOR),
540
                                ]])
541
                            ],
542
                            [
543
                                sg.Column([[
544
                                    sg.Text(" Proxima Factura:", pad=TEXT_PADDING),
545
                                    sg.Text("Serie:", pad=TEXT_PADDING),
546
                                    sg.Input("", key="serie", size=(8, 1)),
547
                                    sg.Text("Folio:", pad=TEXT_PADDING),
548
                                    sg.Input("", key="folio", size=(8, 1)),
549
                                ]],
550
                                    expand_x=True
551
                                )
552
                            ],
553
                            [
554
                                sg.Column([[
555
                                    sg.Text("Complemento Pago:", pad=TEXT_PADDING),
556
                                    sg.Text("Serie:", pad=TEXT_PADDING),
557
                                    sg.Input("", key="serie_pago", size=(8, 1)),
558
                                    sg.Text("", key="folio_pago", pad=TEXT_PADDING),
559
                                ]],
560
                                    expand_x=True
561
                                )
562
                            ],
563
                            [
564
                                sg.Column([[]], size=(40, 40))
565
                            ],
566
                            [
567
                                sg.Column([[
568
                                    sg.Button("Organizar Facturas", key="organizar_facturas", border_width=0),
569
                                ]],
570
                                    expand_x=True
571
                                )
572
                            ],
573
                            [
574
                                sg.Column([[
575
                                    sg.Button("Exportar Metadata ", key="exportar_metadata", border_width=0),
576
                                    sg.Button("Importar Metadata ", key="importar_metadata", border_width=0),
577
                                ]],
578
                                    expand_x=True
579
                                )
580
                            ]
581
                        ],
582
                        key='configuracion_tab',
583
                    ),
584
                ]],
585
                expand_x=True,
586
                expand_y=True,
587
                enable_events=True,
588
                key="main_tab_group",
589
            )
590
        ],
591
        [
592
            sg.Column([[
593
                sg.Push(),
594
                sg.Text("Factura:", pad=TEXT_PADDING),
595
                sg.Text("", key="serie_folio", pad=TEXT_PADDING),
596
                sg.Button(image_data=PREVIEW_ICON, key="ver_preview", border_width=0, button_color=BUTTON_COLOR, disabled=True),
597
                sg.Button("".center(22), disabled=True, key="crear_facturas", border_width=0, button_color=sg.theme_background_color()),
598
                sg.Sizegrip(),
599
            ]],
600
                expand_x=True,
601
            ),
602
        ]
603
    ]
604
605
606
class ActionButtonManager:
607
    def __init__(self, button, preview):
608
        self.name = ""
609
        self.items = []
610
        self.button = button
611
        self.preview = preview
612
613
    def set_items(self, name, items):
614
        self.name = name
615
        self.items = items
616
        self.style_button()
617
618
    def clear(self):
619
        self.name = ""
620
        self.items = []
621
        self.style_button()
622
623
    def text(self):
624
        header = "Procesar"
625
        if self.name == "clientes":
626
            header = "Validar"
627
        elif self.name in ("facturas", "pago"):
628
            header = "Crear"
629
        elif self.name == "correos":
630
            header = "Enviar"
631
        elif self.name == "ajustes":
632
            header = "Enviar"
633
634
        if self.items:
635
            return f"{header} {len(self.items)} {self.name.capitalize()}"
636
        else:
637
            return ""
638
639
    def style_button(self):
640
        self.preview.update(
641
            disabled=not (bool(self.items) and self.name in ("facturas", "pago")),
642
        )
643
        self.button.update(
644
            self.text().center(22),
645
            disabled=not self.items,
646
            button_color=sg.theme_button_color() if self.items else sg.theme_background_color()
647
        )
648