schema updates to rental statuses
This commit is contained in:
@@ -64,15 +64,15 @@ const Rental = sequelize.define("Rental", {
|
||||
"damaged",
|
||||
"lost"
|
||||
),
|
||||
defaultValue: "pending",
|
||||
allowNull: false,
|
||||
},
|
||||
paymentStatus: {
|
||||
type: DataTypes.ENUM("pending", "paid", "refunded", "not_required"),
|
||||
defaultValue: "pending",
|
||||
allowNull: false,
|
||||
},
|
||||
payoutStatus: {
|
||||
type: DataTypes.ENUM("pending", "processing", "completed", "failed"),
|
||||
defaultValue: "pending",
|
||||
type: DataTypes.ENUM("pending", "completed", "failed"),
|
||||
allowNull: true,
|
||||
},
|
||||
payoutProcessedAt: {
|
||||
type: DataTypes.DATE,
|
||||
|
||||
@@ -823,7 +823,7 @@ router.post("/:id/mark-completed", authenticateToken, async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
await rental.update({ status: "completed" });
|
||||
await rental.update({ status: "completed", payoutStatus: "pending" });
|
||||
|
||||
const updatedRental = await Rental.findByPk(rental.id, {
|
||||
include: [
|
||||
@@ -1131,6 +1131,7 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
|
||||
// Item returned on time
|
||||
updatedRental = await rental.update({
|
||||
status: "completed",
|
||||
payoutStatus: "pending",
|
||||
actualReturnDateTime: actualReturnDateTime || rental.endDateTime,
|
||||
notes: notes || null,
|
||||
});
|
||||
@@ -1174,6 +1175,7 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
|
||||
// Item returned damaged
|
||||
const damageUpdates = {
|
||||
status: "damaged",
|
||||
payoutStatus: "pending",
|
||||
actualReturnDateTime: actualReturnDateTime || rental.endDateTime,
|
||||
notes: notes || null,
|
||||
};
|
||||
@@ -1217,6 +1219,7 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
|
||||
// Item reported as lost
|
||||
updatedRental = await rental.update({
|
||||
status: "lost",
|
||||
payoutStatus: "pending",
|
||||
itemLostReportedAt: new Date(),
|
||||
notes: notes || null,
|
||||
});
|
||||
|
||||
@@ -81,6 +81,7 @@ class LateReturnService {
|
||||
const updates = {
|
||||
actualReturnDateTime: new Date(actualReturnDateTime),
|
||||
status: lateCalculation.isLate ? "returned_late" : "completed",
|
||||
payoutStatus: "pending",
|
||||
};
|
||||
|
||||
if (notes) {
|
||||
|
||||
@@ -50,11 +50,6 @@ class PayoutService {
|
||||
throw new Error("Invalid payout amount");
|
||||
}
|
||||
|
||||
// Update status to processing
|
||||
await rental.update({
|
||||
payoutStatus: "processing",
|
||||
});
|
||||
|
||||
// Create Stripe transfer
|
||||
const transfer = await StripeService.createTransfer({
|
||||
amount: rental.payoutAmount,
|
||||
|
||||
@@ -186,11 +186,6 @@ describe('PayoutService', () => {
|
||||
it('should successfully process a rental payout', async () => {
|
||||
const result = await PayoutService.processRentalPayout(mockRental);
|
||||
|
||||
// Verify status update to processing
|
||||
expect(mockRental.update).toHaveBeenNthCalledWith(1, {
|
||||
payoutStatus: 'processing'
|
||||
});
|
||||
|
||||
// Verify Stripe transfer creation
|
||||
expect(mockCreateTransfer).toHaveBeenCalledWith({
|
||||
amount: 9500,
|
||||
@@ -206,7 +201,7 @@ describe('PayoutService', () => {
|
||||
});
|
||||
|
||||
// Verify status update to completed
|
||||
expect(mockRental.update).toHaveBeenNthCalledWith(2, {
|
||||
expect(mockRental.update).toHaveBeenCalledWith({
|
||||
payoutStatus: 'completed',
|
||||
payoutProcessedAt: expect.any(Date),
|
||||
stripeTransferId: 'tr_123456789'
|
||||
@@ -260,13 +255,8 @@ describe('PayoutService', () => {
|
||||
await expect(PayoutService.processRentalPayout(mockRental))
|
||||
.rejects.toThrow('Stripe transfer failed');
|
||||
|
||||
// Verify processing status was set
|
||||
expect(mockRental.update).toHaveBeenNthCalledWith(1, {
|
||||
payoutStatus: 'processing'
|
||||
});
|
||||
|
||||
// Verify failure status was set
|
||||
expect(mockRental.update).toHaveBeenNthCalledWith(2, {
|
||||
expect(mockRental.update).toHaveBeenCalledWith({
|
||||
payoutStatus: 'failed'
|
||||
});
|
||||
|
||||
@@ -296,9 +286,7 @@ describe('PayoutService', () => {
|
||||
});
|
||||
|
||||
const dbError = new Error('Database completion update failed');
|
||||
mockRental.update
|
||||
.mockResolvedValueOnce(true) // processing update succeeds
|
||||
.mockRejectedValueOnce(dbError); // completion update fails
|
||||
mockRental.update.mockRejectedValueOnce(dbError);
|
||||
|
||||
await expect(PayoutService.processRentalPayout(mockRental))
|
||||
.rejects.toThrow('Database completion update failed');
|
||||
@@ -315,16 +303,14 @@ describe('PayoutService', () => {
|
||||
const updateError = new Error('Update failed status failed');
|
||||
|
||||
mockCreateTransfer.mockRejectedValue(stripeError);
|
||||
mockRental.update
|
||||
.mockResolvedValueOnce(true) // processing update succeeds
|
||||
.mockRejectedValueOnce(updateError); // failed status update fails
|
||||
mockRental.update.mockRejectedValueOnce(updateError);
|
||||
|
||||
// The service will throw the update error since it happens in the catch block
|
||||
await expect(PayoutService.processRentalPayout(mockRental))
|
||||
.rejects.toThrow('Update failed status failed');
|
||||
|
||||
// Should still attempt to update to failed status
|
||||
expect(mockRental.update).toHaveBeenNthCalledWith(2, {
|
||||
expect(mockRental.update).toHaveBeenCalledWith({
|
||||
payoutStatus: 'failed'
|
||||
});
|
||||
});
|
||||
|
||||
@@ -211,15 +211,15 @@ const EarningsDashboard: React.FC = () => {
|
||||
className={`badge ${
|
||||
rental.payoutStatus === "completed"
|
||||
? "bg-success"
|
||||
: rental.payoutStatus === "processing"
|
||||
? "bg-warning"
|
||||
: rental.payoutStatus === "failed"
|
||||
? "bg-danger"
|
||||
: "bg-secondary"
|
||||
}`}
|
||||
>
|
||||
{rental.payoutStatus === "completed"
|
||||
? "Paid"
|
||||
: rental.payoutStatus === "processing"
|
||||
? "Processing"
|
||||
: rental.payoutStatus === "failed"
|
||||
? "Failed"
|
||||
: "Pending"}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -147,7 +147,7 @@ export interface Rental {
|
||||
stripePaymentIntentId?: string;
|
||||
stripePaymentMethodId?: string;
|
||||
// Payout status tracking
|
||||
payoutStatus?: "pending" | "processing" | "completed" | "failed";
|
||||
payoutStatus?: "pending" | "completed" | "failed" | null;
|
||||
payoutProcessedAt?: string;
|
||||
stripeTransferId?: string;
|
||||
deliveryMethod: "pickup" | "delivery";
|
||||
|
||||
Reference in New Issue
Block a user