close bolling
This commit is contained in:
@@ -6,7 +6,7 @@ from aws_lambda_powertools.utilities.data_classes import (
|
||||
event_source,
|
||||
)
|
||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||
from layercake.dateutils import now, ttl
|
||||
from layercake.dateutils import fromisoformat, now, ttl
|
||||
from layercake.dynamodb import (
|
||||
DynamoDBPersistenceLayer,
|
||||
KeyPair,
|
||||
@@ -35,12 +35,17 @@ def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
data = enrollment_layer.collection.get_items(
|
||||
TransactKey(enrollment_id) + SortKey('0') + SortKey('author')
|
||||
)
|
||||
created_at: datetime = fromisoformat(data['create_date']) # type: ignore
|
||||
|
||||
if not data:
|
||||
logger.debug('Enrollment not found')
|
||||
return False
|
||||
|
||||
start_date, end_date = get_billing_period(new_image['billing_day'])
|
||||
start_date, end_date = get_billing_period(
|
||||
new_image['billing_day'],
|
||||
year=created_at.year,
|
||||
month=created_at.month,
|
||||
)
|
||||
pk = 'BILLING#ORG#{org_id}'.format(org_id=org_id)
|
||||
sk = 'START#{start}#END#{end}'.format(
|
||||
start=start_date.isoformat(),
|
||||
|
||||
68
order-events/app/events/billing/close_window.py
Normal file
68
order-events/app/events/billing/close_window.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import locale
|
||||
import os
|
||||
from datetime import date
|
||||
|
||||
from aws_lambda_powertools import Logger
|
||||
from aws_lambda_powertools.utilities.data_classes import (
|
||||
EventBridgeEvent,
|
||||
event_source,
|
||||
)
|
||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from layercake.dateutils import fromisoformat
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
from weasyprint import HTML
|
||||
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ORDER_TABLE
|
||||
|
||||
logger = Logger(__name__)
|
||||
order_layer = DynamoDBPersistenceLayer(ORDER_TABLE, dynamodb_client)
|
||||
curdir = os.path.dirname(__file__)
|
||||
env = Environment(loader=FileSystemLoader(curdir))
|
||||
locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8')
|
||||
|
||||
|
||||
def currency(value: float | int) -> str:
|
||||
return locale.currency(value, grouping=True)
|
||||
|
||||
|
||||
def datetime_format(dt: date, fmt='%H:%M %d-%m-%y'):
|
||||
if isinstance(dt, str):
|
||||
dt = fromisoformat(dt) # type: ignore
|
||||
|
||||
return dt.strftime(fmt)
|
||||
|
||||
|
||||
env.filters['datetime_format'] = datetime_format
|
||||
env.filters['currency'] = currency
|
||||
|
||||
|
||||
@event_source(data_class=EventBridgeEvent)
|
||||
@logger.inject_lambda_context
|
||||
def lambda_handler(event: EventBridgeEvent, context: LambdaContext) -> bool:
|
||||
new_image = event.detail['new_image']
|
||||
_, start_date, _, end_date, *_ = new_image['sk'].split('#')
|
||||
|
||||
result = order_layer.collection.query(
|
||||
KeyPair(
|
||||
pk=new_image['id'],
|
||||
sk=f'START#{start_date}#END#{end_date}#ENROLLMENT',
|
||||
),
|
||||
)
|
||||
|
||||
template = env.get_template('tmpl.html')
|
||||
html_rendered = template.render(
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
items=result['items'],
|
||||
)
|
||||
|
||||
HTML(string=html_rendered, base_url='').write_pdf('cert.pdf')
|
||||
|
||||
return order_layer.update_item(
|
||||
key=KeyPair(new_image['id'], new_image['sk']),
|
||||
update_expr='SET #status = :status',
|
||||
expr_attr_names={'#status': 'status'},
|
||||
expr_attr_values={':status': 'CLOSED'},
|
||||
)
|
||||
BIN
order-events/app/events/billing/fonts/SF-Pro.ttf
Executable file
BIN
order-events/app/events/billing/fonts/SF-Pro.ttf
Executable file
Binary file not shown.
200
order-events/app/events/billing/tmpl.html
Normal file
200
order-events/app/events/billing/tmpl.html
Normal file
@@ -0,0 +1,200 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title></title>
|
||||
<meta name="author" content="EDUSEG® <https://eduseg.com.br>" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 0.458cm;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "SF-Pro";
|
||||
src: url("fonts/SF-Pro.ttf") format("truetype");
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
div,
|
||||
h1,
|
||||
h2,
|
||||
ul,
|
||||
p,
|
||||
a {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: SF-Pro;
|
||||
font-size: 11pt;
|
||||
line-height: 1.4;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
section {
|
||||
width: 100%;
|
||||
break-after: page;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: auto;
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid #efefef;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.625rem;
|
||||
}
|
||||
|
||||
tbody > tr > td {
|
||||
border-top: 1px solid #efefef;
|
||||
}
|
||||
|
||||
thead {
|
||||
background-color: #f3f4f680;
|
||||
font-weight: 600;
|
||||
display: table-header-group;
|
||||
}
|
||||
tr {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
.space-y-0\.5 > :not(:last-child) {
|
||||
margin-bottom: 0.125rem;
|
||||
}
|
||||
|
||||
.space-y-2\.5 > :not(:last-child) {
|
||||
margin-bottom: 0.625rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section class="space-y-2.5">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1143.4 257.88"
|
||||
style="width: 10rem"
|
||||
>
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #8cd366;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: #2e3524;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
class="cls-1"
|
||||
d="M119.06,170.25l-53.68-24.18c-1.47-.94-3.35-.94-4.82,0l-53.68,24.18c-2.98,1.9-6.89-.24-6.89-3.77V7.01C0,4.54,2.01,2.54,4.48,2.54h117c2.47,0,4.48,2.01,4.48,4.48v159.46c0,3.54-3.91,5.68-6.89,3.77Z"
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M73.52,57.89H20.82v15.77h52.7v-15.77Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M84.06,86.96H20.82v20.97h63.24v-20.97Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M84.06,23.67H20.82v20.97h63.24v-20.97Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M105.14,102.66c0-2.91-2.36-5.27-5.27-5.27s-5.27,2.36-5.27,5.27,2.36,5.27,5.27,5.27,5.27-2.36,5.27-5.27Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M191.46,2.54h72.24v34.76h-34.54v69.52h30.81v31h-30.81v82.76h34.54v34.76h-72.24V2.54Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M283.8,2.54h45.22c8.38,0,16.01,1.84,22.92,5.52,6.91,3.68,12.35,8.75,16.33,15.17,3.98,6.42,5.97,13.65,5.97,21.65v168.12c0,8-1.94,15.23-5.8,21.65-3.88,6.42-9.26,11.49-16.18,15.17-6.91,3.68-14.65,5.54-23.23,5.54h-45.22V2.54ZM334.52,222.11c1.36-1.46,2.03-3.27,2.03-5.37V41.12c-.2-2.1-1.04-3.89-2.52-5.37-1.47-1.46-3.25-2.22-5.34-2.22h-10.96v190.79h11.27c2.29,0,4.12-.73,5.49-2.22h.02Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M415.84,252.32c-6.81-3.68-12.2-8.73-16.18-15.17-3.97-6.42-5.97-13.63-5.97-21.65V2.54h37.68v218.61c0,2.1.73,3.91,2.2,5.37,1.46,1.48,3.25,2.22,5.34,2.22,2.29,0,4.12-.73,5.49-2.22,1.36-1.46,2.03-3.27,2.03-5.37V2.54h37.68v212.98c0,8.02-1.94,15.23-5.8,21.65-3.88,6.42-9.26,11.49-16.18,15.17-6.92,3.68-14.65,5.54-23.23,5.54s-16.27-1.84-23.08-5.54l.04-.02Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M526.39,252.32c-6.81-3.68-12.2-8.73-16.18-15.17-3.97-6.42-5.97-13.63-5.97-21.65v-61.61h37.68v67.24c0,2.1.73,3.91,2.2,5.37,1.45,1.48,3.25,2.21,5.34,2.21,2.29,0,4.12-.73,5.49-2.21,1.36-1.47,2.03-3.27,2.03-5.37v-60.94c0-4.43-1.73-8.06-5.19-10.91-3.45-2.84-9.05-6.27-16.8-10.27-6.49-3.36-11.78-6.37-15.86-9.01-4.09-2.63-7.6-6.16-10.52-10.59-2.93-4.43-4.4-9.58-4.4-15.49v-61.57c0-8,1.98-15.21,5.97-21.65,3.98-6.42,9.37-11.47,16.18-15.17,6.79-3.68,14.5-5.52,23.08-5.52s16.33,1.84,23.23,5.52c6.91,3.68,12.3,8.75,16.18,15.17,3.88,6.42,5.8,13.65,5.8,21.65v55.62h-37.68v-61.25c0-2.1-.69-3.89-2.03-5.37-1.36-1.46-3.19-2.22-5.49-2.22-2.09,0-3.88.73-5.34,2.22-1.48,1.48-2.2,3.27-2.2,5.37v54.61c0,4.84,1.83,8.81,5.51,11.85,3.66,3.06,9.57,6.91,17.75,11.53,6.29,3.38,11.4,6.33,15.4,8.84,3.97,2.53,7.33,5.84,10.04,9.95,2.72,4.11,4.09,8.81,4.09,14.06v67.94c0,8.02-1.94,15.23-5.8,21.65-3.88,6.42-9.26,11.49-16.18,15.17-6.92,3.68-14.65,5.54-23.23,5.54s-16.27-1.84-23.08-5.54Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M613.84,2.54h72.24v34.76h-34.54v69.52h30.81v31h-30.81v82.76h34.54v34.76h-72.24V2.54Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M720.31,252.32c-4.4-3.27-7.91-7.9-10.52-13.9-2.61-6.01-3.92-12.9-3.92-20.69V42.03c0-7.79,1.98-14.91,5.97-21.33,3.98-6.42,9.43-11.47,16.33-15.17,6.91-3.68,14.56-5.52,22.94-5.52s16.07,1.84,23.08,5.52c7.02,3.68,12.45,8.75,16.33,15.17,3.88,6.42,5.8,13.54,5.8,21.33v73.95h-37.68V36.71c0-2.1-.69-3.89-2.03-5.37-1.36-1.46-3.19-2.22-5.49-2.22-2.09,0-3.88.73-5.34,2.22-1.48,1.48-2.2,3.27-2.2,5.37v181.02c0,2.1.73,3.91,2.2,5.37,1.45,1.48,3.25,2.22,5.34,2.22,2.3,0,4.13-.73,5.49-2.22,1.36-1.47,2.03-3.27,2.03-5.37v-36.02h-9.11v-40.13h46.78v113.76h-37.68v-11.06c-2.31,4.23-5.34,7.42-9.11,9.63-3.77,2.22-8.47,3.32-14.13,3.32s-10.67-1.63-15.08-4.9l-.02-.02Z"
|
||||
/>
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M824.08,19.6h-4.8l-.04-2.89h4.29c.65-.01,1.26-.12,1.82-.31.56-.21,1.01-.5,1.36-.89.34-.4.51-.89.51-1.47,0-.73-.13-1.3-.38-1.73-.24-.43-.65-.73-1.24-.91-.58-.19-1.36-.29-2.35-.29h-2.96v15.98h-3.22V8.24h6.18c1.47,0,2.73.21,3.8.64,1.08.41,1.91,1.05,2.49,1.91.59.84.89,1.9.89,3.18,0,.8-.19,1.51-.56,2.13-.37.62-.92,1.16-1.64,1.62-.71.44-1.59.81-2.62,1.09-.04,0-.1.05-.16.16-.04.1-.09.16-.13.16-.25.15-.42.26-.49.33-.06.06-.13.1-.2.11-.06.01-.24.02-.53.02ZM823.86,19.6l.47-2.2c2.31,0,3.89.5,4.73,1.51.85.99,1.27,2.26,1.27,3.8v1.2c0,.55.02,1.07.07,1.58.06.49.16.9.31,1.24v.36h-3.31c-.15-.39-.24-.93-.27-1.64-.02-.71-.02-1.23-.02-1.56v-1.16c0-1.08-.24-1.87-.73-2.38-.49-.5-1.33-.76-2.51-.76ZM810.38,17.93c0,1.97.33,3.81,1,5.51.68,1.69,1.63,3.17,2.84,4.44,1.22,1.26,2.61,2.24,4.2,2.96,1.6.7,3.3,1.04,5.11,1.04s3.53-.35,5.11-1.04c1.59-.71,2.98-1.7,4.18-2.96,1.2-1.27,2.14-2.76,2.82-4.44.68-1.7,1.02-3.54,1.02-5.51s-.34-3.8-1.02-5.49c-.68-1.69-1.62-3.16-2.82-4.42-1.2-1.26-2.59-2.24-4.18-2.93-1.59-.71-3.29-1.07-5.11-1.07s-3.51.36-5.11,1.07c-1.59.7-2.98,1.67-4.2,2.93-1.22,1.26-2.16,2.73-2.84,4.42-.67,1.69-1,3.52-1,5.49ZM807.75,17.93c0-2.36.41-4.54,1.22-6.55.81-2.01,1.95-3.77,3.4-5.27,1.45-1.51,3.13-2.68,5.02-3.51,1.91-.84,3.96-1.27,6.13-1.27s4.21.42,6.11,1.27c1.91.83,3.59,2,5.02,3.51,1.45,1.5,2.59,3.25,3.4,5.27.83,2.01,1.25,4.2,1.25,6.55s-.42,4.54-1.25,6.55c-.81,2.01-1.95,3.78-3.4,5.31-1.44,1.51-3.11,2.69-5.02,3.53-1.9.84-3.93,1.27-6.11,1.27s-4.22-.42-6.13-1.27c-1.9-.84-3.57-2.02-5.02-3.53-1.45-1.53-2.58-3.3-3.4-5.31-.82-2.01-1.22-4.2-1.22-6.55Z"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<p>
|
||||
Matrículas realizadas entre
|
||||
<strong>{{ start_date|datetime_format('%d/%m/%Y') }}</strong> e
|
||||
<strong>{{ end_date|datetime_format('%d/%m/%Y') }}</strong>
|
||||
</p>
|
||||
|
||||
<table class="table-layout border border-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Curso</td>
|
||||
<td>Colaborador</td>
|
||||
<td>Matrículado em</td>
|
||||
<td>Valor unit.</td>
|
||||
<td>Autor</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for x in items %}
|
||||
<tr>
|
||||
<td>{{ x.course.name }}</td>
|
||||
<td>{{ x.user.name }}</td>
|
||||
<td>
|
||||
{{ x.enrolled_at|datetime_format('%d/%m/%Y, %H:%M')
|
||||
}}
|
||||
</td>
|
||||
<td>{{ x.unit_price|currency }}</td>
|
||||
<td>{{ x.author.name }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
@@ -64,7 +64,28 @@ Resources:
|
||||
detail-type: [INSERT]
|
||||
detail:
|
||||
new_image:
|
||||
sk: ["METADATA#BILLING_TERMS"]
|
||||
sk: ["METADATA#SUBSCRIPTION_COVERED"]
|
||||
|
||||
EventBillingCloseWindowFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
Properties:
|
||||
Handler: events.billing.close_window.lambda_handler
|
||||
LoggingConfig:
|
||||
LogGroup: !Ref EventLog
|
||||
Policies:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref OrderTable
|
||||
Events:
|
||||
Event:
|
||||
Type: EventBridgeRule
|
||||
Properties:
|
||||
Pattern:
|
||||
resources: [!Ref OrderTable]
|
||||
detail-type: [EXPIRE]
|
||||
detail:
|
||||
new_image:
|
||||
sk:
|
||||
- suffix: SCHEDULE#AUTO_CLOSE
|
||||
|
||||
EventAppendOrgIdFunction:
|
||||
Type: AWS::Serverless::Function
|
||||
@@ -128,7 +149,7 @@ Resources:
|
||||
Policies:
|
||||
- DynamoDBWritePolicy:
|
||||
TableName: !Ref OrderTable
|
||||
- DynamoDBWritePolicy:
|
||||
- DynamoDBCrudPolicy:
|
||||
TableName: !Ref EnrollmentTable
|
||||
Events:
|
||||
Event:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey
|
||||
|
||||
import events.reporting.add_item as app
|
||||
import events.billing.append_enrollment as app
|
||||
|
||||
|
||||
def test_add_item(
|
||||
def test_append_enrollment(
|
||||
dynamodb_seeds,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
lambda_context: LambdaContext,
|
||||
@@ -13,7 +13,7 @@ def test_add_item(
|
||||
'detail': {
|
||||
'new_image': {
|
||||
'id': '945e8672-1d72-45c6-b76c-ac06aa8b52ab',
|
||||
'sk': 'METADATA#BILLING_TERMS',
|
||||
'sk': 'METADATA#SUBSCRIPTION_COVERED',
|
||||
'billing_day': 5,
|
||||
'created_at': '2025-07-23T18:09:22.785678-03:00',
|
||||
'org_id': 'edp8njvgQuzNkLx2ySNfAD',
|
||||
@@ -26,5 +26,11 @@ def test_add_item(
|
||||
r = dynamodb_persistence_layer.collection.query(
|
||||
PartitionKey('BILLING#ORG#edp8njvgQuzNkLx2ySNfAD')
|
||||
)
|
||||
items = r['items']
|
||||
|
||||
print(r)
|
||||
assert items[0]['sk'] == 'START#2025-06-05#END#2025-07-04#SCHEDULE#AUTO_CLOSE'
|
||||
assert (
|
||||
items[1]['sk']
|
||||
== 'START#2025-06-05#END#2025-07-04#ENROLLMENT#945e8672-1d72-45c6-b76c-ac06aa8b52ab'
|
||||
)
|
||||
assert items[2]['sk'] == 'START#2025-06-05#END#2025-07-04'
|
||||
29
order-events/tests/events/billing/test_close_window.py
Normal file
29
order-events/tests/events/billing/test_close_window.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey
|
||||
|
||||
import events.billing.close_window as app
|
||||
|
||||
|
||||
def test_append_enrollment(
|
||||
dynamodb_seeds,
|
||||
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
|
||||
lambda_context: LambdaContext,
|
||||
):
|
||||
event = {
|
||||
'detail': {
|
||||
'new_image': {
|
||||
'id': 'BILLING#ORG#BES6dmWgTMXRYmfDyYYXUF',
|
||||
'sk': 'START#2025-07-01#END#2025-07-31#SCHEDULE#AUTO_CLOSE',
|
||||
'created_at': '2025-07-24T15:20:52.464244-03:00',
|
||||
'ttl': 1754017200,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert app.lambda_handler(event, lambda_context) # type: ignore
|
||||
|
||||
# r = dynamodb_persistence_layer.collection.query(
|
||||
# PartitionKey('BILLING#ORG#edp8njvgQuzNkLx2ySNfAD')
|
||||
# )
|
||||
|
||||
# print(r)
|
||||
@@ -14,4 +14,7 @@
|
||||
{"id": {"S": "945e8672-1d72-45c6-b76c-ac06aa8b52ab"}, "sk": {"S": "0"}, "course": {"M": {"id": {"S": "123"}, "name": {"S": "pytest"}}}, "user": {"M": {"id": {"S": "5OxmMjL-ujoR5IMGegQz"}, "name": {"S": "Sérgio R Siqueira"}}}, "create_date": {"S": "2025-06-05T12:13:54.371416+00:00"}}
|
||||
{"id": {"S": "945e8672-1d72-45c6-b76c-ac06aa8b52ab"}, "sk": {"S": "author"}, "name": {"S": "Carolina Brand"}, "user_id": {"S": "SMEXYk5MQkKCzknJpxqr8n"}}
|
||||
{"id": {"S": "CUSTOM_PRICING#ORG#edp8njvgQuzNkLx2ySNfAD"},"sk": {"S": "COURSE#123"},"created_at": {"S": "2025-07-24T16:10:09.304073-03:00"},"unit_price": {"N": "79.2"}}
|
||||
{"id": {"S": "123"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2024-12-30T00:33:33.088916-03:00"},"metadata__konviva_class_id": {"N": "194"},"metadata__unit_price": {"N": "99"},"name": {"S": "Direção Defensiva (08 horas)"},"tenant_id": {"S": "*"},"updated_at": {"S": "2025-07-24T00:00:24.639003-03:00"}}
|
||||
{"id": {"S": "123"},"sk": {"S": "0"},"access_period": {"N": "360"},"cert": {"M": {"exp_interval": {"N": "360"}}},"created_at": {"S": "2024-12-30T00:33:33.088916-03:00"},"metadata__konviva_class_id": {"N": "194"},"metadata__unit_price": {"N": "99"},"name": {"S": "Direção Defensiva (08 horas)"},"tenant_id": {"S": "*"},"updated_at": {"S": "2025-07-24T00:00:24.639003-03:00"}}
|
||||
{"id": {"S": "BILLING#ORG#BES6dmWgTMXRYmfDyYYXUF"},"sk": {"S": "START#2025-07-01#END#2025-07-31"},"created_at": {"S": "2025-07-24T15:20:52.464244-03:00"},"status": {"S": "PENDING"}}
|
||||
{"id": {"S": "BILLING#ORG#BES6dmWgTMXRYmfDyYYXUF"},"sk": {"S": "START#2025-07-01#END#2025-07-31#ENROLLMENT#a08c94a2-7ee4-45fd-bfe7-73568c738b8b"},"author": {"M": {"id": {"S": "SMEXYk5MQkKCzknJpxqr8n"},"name": {"S": "Carolina Brand"}}},"course": {"M": {"id": {"S": "7f7905aa-ec6d-4189-b884-50fa9b1bd0b8"},"name": {"S": "NR-10 Reciclagem: 08 horas"}}},"created_at": {"S": "2025-07-24T16:38:33.095216-03:00"},"enrolled_at": {"S": "2025-07-24T11:26:56.975207-03:00"},"unit_price": {"N": "169"},"user": {"M": {"id": {"S": "iPWidwn4HsYtikiZD33smV"},"name": {"S": "William da Silva Nascimento"}}}}
|
||||
{"id": {"S": "BILLING#ORG#BES6dmWgTMXRYmfDyYYXUF"},"sk": {"S": "START#2025-07-01#END#2025-07-31#ENROLLMENT#ac09e8da-6cb2-4e31-84e7-238df2647a7a"},"author": {"M": {"id": {"S": "SMEXYk5MQkKCzknJpxqr8n"},"name": {"S": "Carolina Brand"}}},"course": {"M": {"id": {"S": "7f7905aa-ec6d-4189-b884-50fa9b1bd0b8"},"name": {"S": "NR-10 Reciclagem: 08 horas"}}},"created_at": {"S": "2025-07-24T16:38:58.694031-03:00"},"enrolled_at": {"S": "2025-07-24T11:26:56.913746-03:00"},"unit_price": {"N": "169"},"user": {"M": {"id": {"S": "ca8c9fca-b508-4842-8a48-fd5cc5632ac0"},"name": {"S": "Geovane Soares De Lima"}}}}
|
||||
Reference in New Issue
Block a user