Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

Commit

Permalink
Merge pull request #107 from Tolfix/dev
Browse files Browse the repository at this point in the history
v3.3
  • Loading branch information
Tolfx authored Apr 17, 2022
2 parents c96fcec + a9ef08f commit 6d7045d
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 110 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cpg-api",
"version": "v3.2",
"version": "v3.3",
"description": "Central Payment Gateway",
"main": "./build/Main.js",
"dependencies": {
Expand Down
10 changes: 10 additions & 0 deletions src/Admin/Commands/Cron.prompt.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { cron_chargeStripePayment, cron_notifyInvoices, cron_notifyLateInvoicePaid } from "../../Cron/Methods/Invoices.cron.methods";
import { cron_createNewInvoicesFromOrders } from "../../Cron/Methods/Orders.cron.methods";
import Logger from "../../Lib/Logger";

export default
Expand All @@ -22,6 +23,10 @@ export default
{
name: 'Invoice late notify',
value: 'run_late_invoice_notify',
},
{
name: "Create invoice from order",
value: 'run_create_invoice_from_order',
}
],
}
Expand All @@ -43,6 +48,11 @@ export default
Logger.info('Running Invoice late notify');
cron_notifyLateInvoicePaid()
}
if(crons.includes('run_create_invoice_from_order'))
{
Logger.info('Running Create invoice from order');
cron_createNewInvoicesFromOrders();
}
return true;
}
}
4 changes: 3 additions & 1 deletion src/Admin/Commands/Invoices.prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,10 @@ export default
}

invoice.paid = true;

invoice.dates.date_paid = getDate();
invoice.markModified('dates');
await invoice.save();
mainEvent.emit("invoice_paid", invoice);
Logger.info(`Invoice with id ${invoiceId} marked as paid`);
break;
}
Expand Down
31 changes: 21 additions & 10 deletions src/Admin/Commands/Orders.prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import mainEvent from "../../Events/Main.event";
import { sendEmail } from "../../Email/Send";
import NewOrderCreated from "../../Email/Templates/Orders/NewOrderCreated";
import { Company_Name } from "../../Config";
import { createInvoiceFromOrder } from "../../Lib/Orders/newInvoice";
import { sendInvoiceEmail } from "../../Lib/Invoices/SendEmail";

export default
{
Expand Down Expand Up @@ -91,7 +93,7 @@ export default
name: 'currency',
type: 'search-list',
message: 'Enter the currency',
choices: currencyCodes
choices: [...currencyCodes, "Customer Currency"]
},
{
name: 'products',
Expand Down Expand Up @@ -178,18 +180,25 @@ export default
}
});

const customer = await CustomerModel.findOne({
id: customer_uid,
});

if(!customer)
throw new Error(`Fail to find customer with id: ${customer_uid}`);

const b_recurring = action2Result.billing_type === "recurring";
const newOrder = await (new OrderModel({
uid: idOrder(),
invoices: [],
currency,
currency: currency === "Customer Currency" ? customer.currency : currency,
customer_uid,
dates: {
createdAt: new Date(),
last_recycle: b_recurring ? dateFormat.format(new Date(), "YYYY-MM-DD") : undefined,
next_recycle: b_recurring ? dateFormat.format(nextRycleDate(new Date(), action2Result.billing_cycle), "YYYY-MM-DD") : undefined,
},
order_status: 'pending',
order_status: 'active',
payment_method,
products: newProduct,
billing_type: action2Result.billing_type,
Expand All @@ -200,13 +209,6 @@ export default

mainEvent.emit("order_created", newOrder);

const customer = await CustomerModel.findOne({
id: customer_uid,
});

if(!customer)
throw new Error(`Fail to find customer with id: ${customer_uid}`);

await sendEmail({
receiver: customer.personal.email,
subject: `New order from ${await Company_Name() !== "" ? await Company_Name() : "CPG"} #${newOrder.id}`,
Expand All @@ -217,6 +219,15 @@ export default

Logger.info(newOrder);

// Creating new invoice
const invoice = await createInvoiceFromOrder(newOrder);
await sendInvoiceEmail(invoice, customer);

newOrder.invoices.push(invoice.id);
await newOrder.save();

Logger.info(`Created new invoice:`, invoice);

break;
}

Expand Down
8 changes: 4 additions & 4 deletions src/Cron/Methods/Invoices.cron.methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import GetText from "../../Translation/GetText";
import CustomerModel from "../../Database/Models/Customers/Customer.model";
import { sendInvoiceEmail, sendLateInvoiceEmail } from "../../Lib/Invoices/SendEmail";
import { ChargeCustomer } from "../../Payments/Stripe";
import { InvoiceNotifiedReport } from "../../Email/Reports/InvoiceReport";
import { InvoiceLateReport, InvoiceNotifiedReport } from "../../Email/Reports/InvoiceReport";
import mainEvent from "../../Events/Main.event";
import { getDate } from "../../Lib/Time";

Expand Down Expand Up @@ -44,7 +44,7 @@ export function cron_notifyInvoices()
for await(const invoice of invoices)
{
// Get customer
const Customer = await CustomerModel.findOne({ id: invoice.customer_uid});
const Customer = await CustomerModel.findOne({ id: invoice.customer_uid });
if(!Customer)
continue;

Expand Down Expand Up @@ -143,9 +143,9 @@ export function cron_notifyLateInvoicePaid()
const Customer = await CustomerModel.findOne({ id: invoice.customer_uid});
if(!Customer)
continue;

await sendLateInvoiceEmail(invoice, Customer);

}
if(invoices.length > 0)
await InvoiceLateReport(invoices);
});
}
55 changes: 55 additions & 0 deletions src/Cron/Methods/Orders.cron.methods.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Default_Language, d_Days } from "../../Config";
import OrderModel from "../../Database/Models/Orders.model";
import Logger from "../../Lib/Logger";
import GetText from "../../Translation/GetText";
import dateFormat from "date-and-time";
import nextRecycleDate from "../../Lib/Dates/DateCycle";
import { createInvoiceFromOrder } from "../../Lib/Orders/newInvoice";
import { InvoiceCreatedReport } from "../../Email/Reports/InvoiceReport";

// Logger.info(`Checking orders..`);
export function cron_createNewInvoicesFromOrders()
{
Logger.info(GetText(Default_Language).cron.txt_Orders_Checking);
// Check if the order needs to create a new invoice if order.dates.next_recycle is withing 14 days
OrderModel.find({
order_status: "active",
// order_status: {
// $not: /fraud|cancelled|draft|refunded/g
// }
}).then(async orders =>
{
const newInvoices = [];
// orders.forEach(async order => {
for await(const order of orders)
{
Logger.info(GetText(Default_Language).cron.txt_Order_Checking(order.id));
// Logger.info(`Checking order ${order.id}`);
// Check if order.order_status is not "cancelled" or "fraud"
if(order.dates.next_recycle)
if(dateFormat.parse(order.dates.next_recycle, "YYYY-MM-DD").getTime() - new Date().getTime() <= d_Days * 24 * 60 * 60 * 1000)
{
const temptNextRecycle = order.dates.next_recycle;
order.dates.last_recycle = temptNextRecycle;
// Update order.dates.next_recycle
order.dates.next_recycle = dateFormat.format(nextRecycleDate(
dateFormat.parse(temptNextRecycle, "YYYY-MM-DD"), order.billing_cycle ?? "monthly")
, "YYYY-MM-DD");
// Create a new invoice
const newInvoice = await createInvoiceFromOrder(order);
newInvoices.push(newInvoice);

// Save the invoice in order.invoices array
order.invoices.push(newInvoice.id);

// mark order updated in dates
order.markModified("dates");
order.markModified("invoices");
// Save the order
await order.save();
}
if(newInvoices.length > 0)
await InvoiceCreatedReport(newInvoices);
}
});
}
55 changes: 2 additions & 53 deletions src/Cron/Orders.cron.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,11 @@
import { CronJob } from "cron";
import OrderModel from "../Database/Models/Orders.model";
import Logger from "../Lib/Logger";
import dateFormat from "date-and-time";
import { createInvoiceFromOrder } from "../Lib/Orders/newInvoice";
import nextRecycleDate from "../Lib/Dates/DateCycle";
import { Default_Language, d_Days } from "../Config";
import { InvoiceCreatedReport } from "../Email/Reports/InvoiceReport";
import GetText from "../Translation/GetText";
import { cron_createNewInvoicesFromOrders } from "./Methods/Orders.cron.methods";

export = function Cron_Orders()
{
// Every hour
new CronJob("0 12 * * *", () =>
{
Logger.info(GetText(Default_Language).cron.txt_Orders_Checking);
// Logger.info(`Checking orders..`);

// Check if the order needs to create a new invoice if order.dates.next_recycle is withing 14 days
OrderModel.find({
order_status: "active",
// order_status: {
// $not: /fraud|cancelled|draft|refunded/g
// }
}).then(async orders =>
{
const newInvoices = [];
// orders.forEach(async order => {
for await(const order of orders)
{
Logger.info(GetText(Default_Language).cron.txt_Order_Checking(order.id));
// Logger.info(`Checking order ${order.id}`);
// Check if order.order_status is not "cancelled" or "fraud"
if(order.dates.next_recycle)
if(dateFormat.parse(order.dates.next_recycle, "YYYY-MM-DD").getTime() - new Date().getTime() <= d_Days * 24 * 60 * 60 * 1000)
{
const temptNextRecycle = order.dates.next_recycle;
order.dates.last_recycle = temptNextRecycle;
// Update order.dates.next_recycle
order.dates.next_recycle = dateFormat.format(nextRecycleDate(
dateFormat.parse(temptNextRecycle, "YYYY-MM-DD"), order.billing_cycle ?? "monthly")
, "YYYY-MM-DD");
// Create a new invoice
const newInvoice = await createInvoiceFromOrder(order);
newInvoices.push(newInvoice);

// Save the invoice in order.invoices array
order.invoices.push(newInvoice.id);

// mark order updated in dates
order.markModified("dates");
order.markModified("invoices");
// Save the order
await order.save();
}
if(newInvoices.length > 0)
await InvoiceCreatedReport(newInvoices);
}
});

cron_createNewInvoicesFromOrders();
}, null, true, "Europe/Stockholm");
}
80 changes: 44 additions & 36 deletions src/Email/Reports/InvoiceReport.ts
Original file line number Diff line number Diff line change
@@ -1,71 +1,79 @@
import { GetSMTPEmails } from "../../Config";
import { IInvoice } from "@interface/Invoice.interface";
import { SendEmail } from "../Send";
import UseStyles from "../Templates/General/UseStyles";
import { stripIndent } from "common-tags";

export const InvoiceNotifiedReport = async (invoices: IInvoice[]) =>
{
GetSMTPEmails().then((emails) =>
GetSMTPEmails().then(async (emails) =>
{
for(const email of emails)
for await(const email of emails)
{
SendEmail(email, "Invoice(s) Notified", {
isHTML: true,
body: `
<h1>Invoice(s) Notified</h1>
<p>
${invoices.length} invoices have been notified.
</p>
<p>
The following invoices have been notified:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
`
body: await UseStyles(stripIndent`
<div>
<h1>Invoice(s) Notified</h1>
<p>
${invoices.length} invoices have been notified.
</p>
<p>
The following invoices have been notified:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
</div>
`)
});
}
})
};

export const InvoiceLateReport = async (invoices: IInvoice[]) =>
{
GetSMTPEmails().then((emails) =>
GetSMTPEmails().then(async (emails) =>
{
for(const email of emails)
for await(const email of emails)
{
SendEmail(email, "Invoice(s) Late Reminder", {
isHTML: true,
body: `
<h1>Invoice(s) Reminded</h1>
<p>
${invoices.length} invoices have been reminded.
</p>
<p>
The following invoices have been reminded:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
`
body: await UseStyles(stripIndent`
<div>
<h1>Invoice(s) Reminded</h1>
<p>
${invoices.length} invoices have been reminded.
</p>
<p>
The following invoices have been reminded:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
</div>
`)
});
}
})
};

export const InvoiceCreatedReport = async (invoices: IInvoice[]) =>
{
GetSMTPEmails().then((emails) =>
GetSMTPEmails().then(async (emails) =>
{
for(const email of emails)
for await(const email of emails)
{
SendEmail(email, "Invoice(s) Created", {
isHTML: true,
body: `
<h1>Invoice(s) Created</h1>
<p>
${invoices.length} invoices have been created.
</p>
<p>
The following invoices have been created:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
`
body: await UseStyles(stripIndent`
<div>
<h1>Invoice(s) Created</h1>
<p>
${invoices.length} invoices have been created.
</p>
<p>
The following invoices have been created:
${invoices.map((invoice) => `<br><strong>${invoice.id}</strong>`).join("")}
</p>
</div>
`)
});
}
})
Expand Down
Loading

0 comments on commit 6d7045d

Please sign in to comment.